-
Notifications
You must be signed in to change notification settings - Fork 0
/
mv.Process.ProcessCleanup.pas
67 lines (55 loc) · 1.54 KB
/
mv.Process.ProcessCleanup.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
unit mv.Process.ProcessCleanup;
interface
uses
Windows, SysUtils, TlHelp32;
function GetChildProcesses(ParentPID: DWORD): TArray<DWORD>;
procedure TerminateProcessTree(PID: DWORD);
implementation
// Get the direct child processes of a given process
function GetChildProcesses(ParentPID: DWORD): TArray<DWORD>;
var
hSnapshot: THandle;
pe: TProcessEntry32;
ChildPIDs: TArray<DWORD>;
begin
hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if hSnapshot = INVALID_HANDLE_VALUE then Exit;
try
pe.dwSize := SizeOf(pe);
if Process32First(hSnapshot, pe) then
begin
repeat
if pe.th32ParentProcessID = ParentPID then
begin
SetLength(ChildPIDs, Length(ChildPIDs) + 1);
ChildPIDs[High(ChildPIDs)] := pe.th32ProcessID;
end;
until not Process32Next(hSnapshot, pe);
end;
finally
CloseHandle(hSnapshot);
end;
Result := ChildPIDs;
end;
// Recursively terminate the process tree
procedure TerminateProcessTree(PID: DWORD);
var
ChildPIDs: TArray<DWORD>;
ProcessHandle: THandle;
I: Integer;
begin
// First, get child processes and terminate their trees
ChildPIDs := GetChildProcesses(PID);
for I := 0 to High(ChildPIDs) do
TerminateProcessTree(ChildPIDs[I]);
// Now, terminate the given process
ProcessHandle := OpenProcess(PROCESS_TERMINATE, False, PID);
if ProcessHandle <> 0 then
try
TerminateProcess(ProcessHandle, 0);
finally
CloseHandle(ProcessHandle);
end;
end;
end.
end.