【发布时间】:2022-01-07 17:32:52
【问题描述】:
以下代码可以“杀死 -9”我的进程(见下文)。但我宁愿不要仅仅为了从我的 C++ 程序中杀死一个进程而使用 cmd.exe。是否有一种纯粹的 Win32 API 方式来执行此操作,特别是具有“/T 和 /F”标志的效果。我不得不相信这是可能的,因为 taskkill.exe 是用 Win32 API 编写的。
#include <iostream>
#include <string>
void KillDash9(unsigned long PID) {
std::string killcmd = std::string("")
+ std::string("taskkill /T /F /PID ")
+ std::to_string(PID);
std::cout << killcmd << std::endl;
system(killcmd.c_str());
}
以下是我尝试过但不起作用的方法:
void KillDash9_v2(unsigned long PID) {
HANDLE pHandle = OpenProcess(
/*[in] DWORD dwDesiredAccess*/ PROCESS_TERMINATE | SYNCHRONIZE,
/*[in] BOOL bInheritHandle*/ TRUE,
/*[in] DWORD dwProcessId*/ PID
);
TerminateProcess(pHandle, 0);
WaitForSingleObject(pHandle, 500);
CloseHandle(pHandle);
}
KillDash9_v2() 不会终止进程:
"powershell -command ping -t localhost"
但是,KillDash9_v1() 可以杀死这个进程。
如何让 KillDash9_v2() 以同样的方式工作? v2会杀死powershell(3328),但不会杀死在杀死7236后继续运行的ping.exe(7236)。我需要以某种方式枚举从7246开始的进程树并杀死它下面的每个分支。
我按照建议添加了错误检查。
void KillDash9_v3(unsigned long PID) {
// Clear Windows Error Variable
SetLastError(0);
HANDLE pHandle = OpenProcess(
/*[in] DWORD dwDesiredAccess*/ PROCESS_TERMINATE | SYNCHRONIZE,
/*[in] BOOL bInheritHandle*/ FALSE,
/*[in] DWORD dwProcessId*/ PID
);
if (pHandle == nullptr) {
long int err = GetLastError();
std::string msg = std::string("ERROR : OpenProcess failed for PID(") + std::to_string(PID) + std::string(")\n")
+ std::string("REASON : ") + WindowsGetErrorString(err) + std::string("\n")
+ std::string("CODE : ") + std::to_string(err) + std::string("\n");
std::cout << msg;
return;
}
// Clear Windows Error Variable
SetLastError(0);
BOOL rc = TerminateProcess(pHandle, 0);
if (rc == 0) {
long int err = GetLastError();
std::string msg = std::string("ERROR: TerminateProcess failed for PID(") + std::to_string(PID) + std::string(")\n")
+ std::string("REASON: ") + WindowsGetErrorString(err) + std::string("\n")
+ std::string("CODE : ") + std::to_string(err) + std::string("\n");
std::cout << msg;
return;
}
WaitForSingleObject(pHandle, 500);
CloseHandle(pHandle);
}
【问题讨论】:
-
你应该检查
OpenProcess返回的句柄是否有效。浏览它的文档 -
它必须是有价值的,因为它适用于 taskkill.exe...为什么 TerminateProcess 不是相同的 PID?
-
由于进程访问权限,
OpenProcess可能会失败。这就是为什么你应该检查它返回的句柄是否有效。 -
好建议...我试试看。
-
@pico 不过,有一种更简单的方法可以杀死生成的进程树。使用
CreateProcess...()生成新进程时,将新进程放入作业对象中。它创建的任何子进程也将被放入同一个作业中(默认情况下,可以被覆盖)。然后你可以简单地terminate the job object。