Laufende Anwendung beenden |
|
| System | Win9x, WinNT, Win2000, WinXP, Vista, Win7 |
|---|---|
| Ab Delphi-Version | Delphi 1 |
| Letzte Änderung | 21.01.2012 |
Die Funktion beendet den Prozess, der mit dem übergebenen Exe-Namen oder der angegebenen Prozess-ID übereinstimmt. Sollten mehrere Prozesse desselben Exe-Namens laufen, so wird entweder der zuerst gefundene geschlossen (AKillAll = False) oder alle (AKillAll = True) - diese Angabe ist natürlich nur beim Beenden des Prozesses über den Prozessnamen möglich. Wenn der Prozess mit allen gestarteten Kind-Prozessen beendet werden soll, muss AKillStructure auf True gesetzt werden.
Sobald der Prozess (sowie alle Unterprozesse) erfolgreich beendet wurde, wird True zurückgegeben.
Function KillTask(Const APID: Cardinal;
Const AKillStructure: Boolean = False): Boolean; Overload;
Var
P: TProcessEntry32;
H: THandle;
D: DWORD;
TP: TTokenPrivileges;
hToken: THandle;
hProcess: Cardinal;
Goon: Boolean;
Function IsWinNT: Boolean;
Var
VI: TOSVersionInfo;
Begin
VI.dwOSVersionInfoSize := SizeOf(VI);
Result := False;
If GetVersionEx(VI) Then
Result := VI.dwPlatformId = VER_PLATFORM_WIN32_NT;
End;
Begin
Result := False;
P.dwSize := SizeOf(P);
H := CreateToolHelp32Snapshot(TH32CS_SnapProcess, 0);
Goon := True;
Try
If Process32First(H, P) Then Begin
Result := True;
Repeat
If P.th32ProcessID = APID Then Begin
If IsWinNT Then Begin
If OpenProcessToken(GetCurrentProcess,
TOKEN_ADJUST_PRIVILEGES, hToken) Then Begin
LookupPrivilegeValue(NIL, 'SeDebugPrivilege',
TP.Privileges[0].Luid);
TP.PrivilegeCount := 1;
TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
D := 0;
AdjustTokenPrivileges(hToken, False, TP, 0,
PTokenPrivileges(NIL)^, D);
CloseHandle(hToken);
End;
hProcess := OpenProcess(Process_Terminate, False,
P.th32ProcessID);
Goon := False;
If hProcess <> 0 Then
Try
Result := TerminateProcess(hProcess, 0) And Result;
If WaitForSingleObject(hProcess, INFINITE) <> WAIT_OBJECT_0 Then
Result := False;
Finally
CloseHandle(hProcess);
End;
End;
End Else If (AKillStructure) And (P.th32ParentProcessID = APID) Then
Result := KillTask(P.th32ProcessID, True) And Result;
Until (Not Process32Next(H, P)) Or ((Not Goon) And (Not AKillStructure));
End;
Finally
CloseHandle(H);
End;
End;
Function KillTask(Const AExeName: String; Const AKillAll: Boolean = False;
Const AKillStructure: Boolean = False): Boolean; Overload;
Var
P: TProcessEntry32;
H: THandle;
Begin
Result := False;
P.dwSize := SizeOf(P);
H := CreateToolHelp32Snapshot(TH32CS_SnapProcess, 0);
Try
If Process32First(H, P) Then Begin
Result := True;
Repeat
If AnsiLowerCase(P.szExeFile) = AnsiLowerCase(AExeName) Then Begin
Result := KillTask(P.th32ProcessID, AKillStructure) And Result;
If Not AKillAll Then
Break;
End;
Until (Not Process32Next(H, P));
End;
Finally
CloseHandle(H);
End;
End;
Wenn der Prozess auf diese Weise beendet wird, ist Datenverlust möglich. Der Prozess wird beendet, ohne dass dabei Rücksicht auf eventuelle Rückmeldungen genommen wird. Wenn Prozesse, die nicht unter dem eigenen Benutzerkonto ausgeführt werden (wie Systemprozesse), beendet werden sollen, sind Administratorenrechte erforderlich.
Wenn nur versucht werden soll, den Prozess dazu zu bringen, sich selbst zu beenden, kann folgende Prozedur verwendet werden:
Var
PID: Cardinal;
Wait: Boolean;
Begin
Result := True;
If GetParent(WND) = 0 Then
GetWindowThreadProcessID(WND, PID);
If (lParam And (-1)) = -1 Then Begin
Wait := True;
lParam := (lParam And (Not (-1)));
End Else
Wait := False;
If PID = lParam Then
If Wait Then
SendMessage(WND, WM_CLOSE, 0, 0)
Else
PostMessage(WND, WM_CLOSE, 0, 0);
End;
Procedure TryKillTask(PID: Cardinal; Wait: Boolean = True);
Var
Flag: LPARAM;
Begin
If Wait Then
Flag := PID And (-1)
Else
Flag := PID;
EnumWindows(@EnumWindowsCallback, Flag);
End;
Wenn TryKillTask aufgerufen wird, muss die Prozess-ID übergeben werden (diese kann wie in der Routine in "KillTask mit String" ermittelt werden). Wenn Wait True ist, pausiert das eigene Programm, bis das Fremdprogramm die Nachricht verarbeitet hat - falls sich also ein Dialog öffnet (wie "Wollen Sie speichern?"), wartet das eigene Programm darauf. Während dieser Zeit kann es nicht bedient werden. Um sicher zu gehen, könnte man noch versuchen, anschließend die Existenz dieses Taskes zu überprüfen (oder einfach KillTask mit der PID direkt aufrufen - falls der Task bereits beendet wurde, geschieht nichts).
- Verwendung von CreateProcess
- Herausfinden, ob ein bestimmtes Programm gerade läuft
- Anwendung für eine bestimmte Zeit pausieren
- Mehrfachstart verhindern
- Programm vor dem Taskmanager verstecken
- Alle sichtbaren Fenster minimieren/wiederherstellen
- Ermitteln ob eine Exe-Datei läuft
- Auflisten aller Fenster
- Button klicken
- Beliebige Fenster minimieren, maximieren