Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Externes Programm beenden (https://www.delphipraxis.net/175823-externes-programm-beenden.html)

SKarin 22. Jul 2013 10:47

Externes Programm beenden
 
:( Hallo,
ich benutze Delphi XE 3 und habe einen Service (Windows Dienst)geschrieben, mit dem ich ein externes Programm starten kann. Das funktioniert mit WinExec auch gut. Jetzt möchte ich das gleiche Programm beenden. Ich suche schon seit Tagen nach Lösungen und habe schon sämtliche Prozeduren KillTask oder KillProcess oder EnumWindowsCallback eingebunden, leider alles ohne Erfolg. Gibt es vielleicht noch eine andere Möglichkeit, um externe exe-files zu beenden? Der Name der Datei ist bekannt und es gibt sie wirklich, ich hatte sie ja vorher geöffnet. Um sicher zu gehen, dass es nicht am Service liegt, habe ich nun eine eigenständiges Programm geschrieben. Aber auch hier kann ich ein über das Programm geöffnetes externes Programm nicht schließen.
Kann mir jemand helfen?:?

Der schöne Günther 22. Jul 2013 10:55

AW: Externes Programm beenden
 
Delphi-Quellcode:
WinExec
gibt nichts zurück, womit man vernünftig weiter arbeiten könnte (wie eine Prozess-ID). KillTask oder KillProcess sagt mir spontan nichts, wie EnumWindows dir hier weiterhelfen soll, versrtehe ich nicht.

Starte den Prozess "einfach" mit CreateProcess (ja, das Teil hat eine lange Parameterliste), dann hast du auch bsp. die Prozess-ID, damit kannst du den Prozess mittels TerminateProcess() einfach abschießen. Falls du das wirklich willst.

arnof 22. Jul 2013 11:11

AW: Externes Programm beenden
 
wenn Du die ProzessID hast, dann:

Code:
 
 if (ProcessID<>0) then begin
   Ph:= OpenProcess(1, BOOL(0), ProcessID);
   Ret := TerminateProcess(Ph, 0);
 end;

Der schöne Günther 22. Jul 2013 11:18

AW: Externes Programm beenden
 
Wobei TerminateProcess schon wirklich rabiat ist, das ist als würde man ihn hinterrücks erschießen - Der Prozess sieht es nicht kommen und kann darauf nicht mehr reagieren. Da du erst mit EnumWindows hantiert hast - vielleicht möchtest du den Prozess eher freundlich beenden? Dann könntest du nach seinem Fenster suchen und ihm eine
Delphi-Quellcode:
WM_CLOSE
-Nachricht senden.

Ob einem das Wissen, wie die .exe-Datei nun heißt überhaupt weiterhilft... Ich glaube nicht. Ich habe bislang immer externe Programme mittels
Delphi-Quellcode:
CreateProcess
gestartet und am Schluss eine
Delphi-Quellcode:
WM_CLOSE
geschickt. Waren sie nach einer Zeitspanne immer noch da, weitere
Delphi-Quellcode:
WM_CLOSE
. Waren sie dann immer noch da, wurde das sofortige Todesurteil mittels
Delphi-Quellcode:
TerminateProcess
vollstreckt. :smile2:

arnof 22. Jul 2013 11:52

AW: Externes Programm beenden
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1222248)
Wobei TerminateProcess schon wirklich rabiat ist, das ist als würde man ihn hinterrücks erschießen - Der Prozess sieht es nicht kommen und kann darauf nicht mehr reagieren. Da du erst mit EnumWindows hantiert hast - vielleicht möchtest du den Prozess eher freundlich beenden? Dann könntest du nach seinem Fenster suchen und ihm eine
Delphi-Quellcode:
WM_CLOSE
-Nachricht senden.

Ob einem das Wissen, wie die .exe-Datei nun heißt überhaupt weiterhilft... Ich glaube nicht. Ich habe bislang immer externe Programme mittels
Delphi-Quellcode:
CreateProcess
gestartet und am Schluss eine
Delphi-Quellcode:
WM_CLOSE
geschickt. Waren sie nach einer Zeitspanne immer noch da, weitere
Delphi-Quellcode:
WM_CLOSE
. Waren sie dann immer noch da, wurde das sofortige Todesurteil mittels
Delphi-Quellcode:
TerminateProcess
vollstreckt. :smile2:

Manche Prozesse wollen es ja nicht kommen sehen und sind penetrant. Ich habe das in ein Fahre den PC herunter Programm reinmachen müssen, da das manche Prozesse blockierten, weil die sich für wichtig halten :lol:

SKarin 22. Jul 2013 12:11

AW: Externes Programm beenden
 
Hallo,
jetzt klappt es.
Ich habe folgende Procedure verwendet:
procedure TForm1.Killprocess(Name:String);
var
PEHandle,hproc: cardinal;
PE: ProcessEntry32;
begin
//NTSetPrivilege(SE_DEBUG_NAME,True);
PEHandle := CreateTOOLHelp32Snapshot(TH32cs_Snapprocess,0);
if PEHandle <> Invalid_Handle_Value then
begin
PE.dwSize := Sizeof(ProcessEntry32);
Process32first(PEHandle,PE);

repeat
if Lowercase(PE.szExeFile) = Lowercase(Pchar(Name)) then
begin
hproc := openprocess(Process_Terminate,false,pe.th32Process ID);
TerminateProcess(hproc,0);
closehandle(hproc);
end;
until Process32next(PEHandle,PE)=false;
end;
closehandle(PEHandle);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Killprocess ( 'notepad.exe');
end;

SKarin 22. Jul 2013 12:17

AW: Externes Programm beenden
 
Vielen Dank für Eure Hilfe. Jetzt kann ich erst einmal weiterbauen und das nächste Problem angehen.

Der schöne Günther 22. Jul 2013 12:24

AW: Externes Programm beenden
 
Super :-)

Ich weiß zwar nicht, was im Windows-Jargon überhaupt genau als 'Snapshot' bezeichnet wird, aber das sieht ziemlich zeitaufwändig aus. Außerdem schießt du damit direkt alle Prozesse erbarmungslos ab, die das Unglück haben, so zu heißen. Mir wäre das zu unsicher: Ich hätte mir lieber am Anfang gemerkt, was ich selbst gestartet habe, damit ich am Ende auch genau das wieder zu machen kann. Wenn dein Anwender nun selbst gerade in einer notepad-Instanz an einem Roman schreibt, schießt du dem das auch direkt ungefragt mit ab.

Klar, in deinem Praxisfall wird es wohl nicht notepad sein, aber ich meine nur ;-)

DeddyH 22. Jul 2013 12:33

AW: Externes Programm beenden
 
Das sehe ich ähnlich, mit dem erwähnten CreateProcess oder auch mit ShellExecuteEx hätte man ja das ProcessHandle. Dann könnte man alle Fenster durchgehen (EnumWindows), deren Prozesshandle ermitteln (GetWindowThreadProcessID), vergleichen und sie bei Treffer höflichst auffordern, sich zu verdünnisieren (WM_CLOSE). Wenn das nicht fruchtet, kann man den Prozess ja dann immer noch abschießen.

Union 22. Jul 2013 12:44

AW: Externes Programm beenden
 
Bitte tagge Deinen Sourcecode, dann ist der besser zu lesen.

Dalai 22. Jul 2013 13:15

AW: Externes Programm beenden
 
Es gibt tatsächlich im Jahr 2013 Leute, die WinExec verwenden, eine Funktion, die schon seit Win9x-Zeiten tot ist? Wow! Welchen Vorteil gewinnt man damit gegenüber ShellExecute(Ex)?

Und bzgl. deiner Methode zum Abschießen der Prozesse kann ich mich dem schönen Günther und DeddyH nur anschließen: Einfach alle gleichnamigen Prozesse abzuschießen gehört sich nicht (es sei denn, man hat einen sehr guten Grund dafür)!

MfG Dalai

Luckie 22. Jul 2013 13:26

AW: Externes Programm beenden
 
Mit EnumWindows dürfte er nicht weiter kommen. Ein Dienst läuft in einer anderen Windows Station und sieht die Fenster des Benutzers gar nicht.

Union 22. Jul 2013 13:32

AW: Externes Programm beenden
 
Zitat:

Zitat von Luckie (Beitrag 1222268)
Mit EnumWindows dürfte er nicht weiter kommen. Ein Dienst läuft in einer anderen Windows Station und sieht die Fenster des Benutzers gar nicht.

Normalerweise... Aber dafür gibt es ja OpenWindowStation, SetProcessWindowStation, GetUserObjectInformation, OpenDesktop, SetThreadDesktop und Konsorten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz