[英]How to kill a process started by .BAT file, which was started by CreateProcess?
例如:
var
sParams: string;
SI: TStartupInfo;
PI: TProcessInformation;
begin
FillChar(SI, SizeOf(SI), #0);
FillChar(PI, SizeOf(PI), #0);
with SI do
begin
cb := SizeOf(SI);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := SW_SHOW
end;
sParams := 'ping 127.0.0.1 -t';
UniqueString(sParams);
if CreateProcess(nil, PChar(sParams), nil, nil, False, 0, nil, nil, SI, PI) then
FProcessHandle := PI.hProcess;
如果我调用TerminateProcess(FProcessHandle, 0)
控制台成功关闭并且进程ping
终止。
但是有:
sParams := 'run.bat';
及其内容
ping 127.0.0.1 -t
调用TerminateProcess(FProcessHandle, 0)
也成功,但进程ping
继续运行。 如何杀死那个由 BAT 文件启动的进程?
TerminateProcess
只是杀死一个进程。 当您运行该 .bat 时,进程树将如下所示:
you.exe
|
\ cmd.exe /c run.bat
|
\ ping.exe 127.0.0.1 -t
要终止子进程及其子进程,您需要使用作业对象。 启动暂停的子进程,将其添加到作业中,然后恢复其线程。
通过将代码中的PI.dwProcessId
作为 PID 参数传递来使用以下函数。
function KillProcessTree(const PID: Cardinal): boolean;
var hProc, hSnap,
hChildProc : THandle;
pe : TProcessEntry32;
bCont : BOOL;
begin
Result := true;
FillChar(pe, SizeOf(pe), #0);
pe.dwSize := SizeOf(pe);
hSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap <> INVALID_HANDLE_VALUE) then
begin
if (Process32First(hSnap, pe)) then
begin
hProc := OpenProcess(PROCESS_ALL_ACCESS, false, PID);
if (hProc <> 0) then
begin
Result := Result and TerminateProcess(hProc, 1);
WaitForSingleObject(hProc, INFINITE);
CloseHandle(hProc);
end;
bCont := true;
while bCont do
begin
if (pe.th32ParentProcessID = PID) then
begin
KillProcessTree(pe.th32ProcessID);
hChildProc := OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
if (hChildProc <> 0) then
begin
Result := Result and TerminateProcess(hChildProc, 1);
WaitForSingleObject(hChildProc, INFINITE);
CloseHandle(hChildProc);
end;
end;
bCont := Process32Next(hSnap, pe);
end;
end;
CloseHandle(hSnap);
end;
end;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.