【问题标题】:Way to kill a process programmatically by PID通过 PID 以编程方式杀死进程的方法
【发布时间】:2019-04-12 00:04:26
【问题描述】:

工作环境:c++、windows

我想存储所有 pid(不是进程名称),然后在我想终止时以编程方式终止进程。 我知道我可以使用 system("taskkill /pid xxxx") 杀死一个进程,但我想知道更好/最好的方法来通过 pid 杀死一个进程。 终止进程的最佳方法是什么?为什么?

【问题讨论】:

  • 终止进程的最佳方法是什么?为什么? 发送消息并礼貌地要求它在安全的情况下关闭。产生不良副作用的空间要小得多。

标签: c++ windows process


【解决方案1】:

幸运的是,一旦你有了 PID,就很容易杀死它。

  1. OpenProcess从PID获取进程句柄
    • 请务必指定PROCESS_TERMINATE 权限。
  2. TerminateProcess 杀死进程

【讨论】:

  • 我应该在终止进程之前检查进程是否正在运行吗?如果进程不存在怎么办?
  • @lll:如果进程不存在,您对OpenProcess 的调用将失败,并返回NULL。您可以检测到它并打印出一条错误消息,或者您可以忽略它是NULL 的事实,并将其传递给TerminateProcess(当然,它也会失败)。
  • 这与没有 /F 选项的 taskkill.exe 不同,后者将 WM_CLOSE 发送到应用程序的顶级和仅消息窗口(通过枚举会话并通过GetWindowThreadProcessId 将窗口映射到进程)。发送关闭消息允许进程正常退出。首先优雅地尝试一下,如果应用程序在超时后仍在运行,则回退到OpenProcessTerminateProcess
  • 如果一个进程没有窗口,那么它可能是一个控制台进程,但不是控制台会话中的主导进程(即不是控制台窗口的有效所有者;conhost.exe是真正的所有者,但系统说的是善意的谎言)。您可以尝试AttachConsole(pid),如果成功,则调用SetConsoleCtrlHandler 忽略进程中的控制事件,并调用GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0) 将Ctrl+Break 发送到连接到控制台的所有进程。杀死连接到控制台的所有进程是可疑的,但并不比 taskkill.exe 已经为主要控制台进程所做的更重要。
【解决方案2】:

您可以使用 OpenProcess() 和 TerminateProcess() 终止进程。代码将如下所示:

HANDLE handle = OpenProcess(PROCESS_TERMINATE, FALSE, ProcessID);
if (NULL != handle) {   
    TerminateProcess(handle, 0);
    CloseHandle(handle);
}

对于使用system("taskkill /pid xxxx")的不便,我邀请您阅读this post。已经给出了大量的答案来解释为什么不使用这个表达式。

  • 慢:必须跳过大量不必要的 Windows 代码和单独的程序才能进行简单操作。

  • 不可移植:依赖于暂停程序。

  • 不好的风格:只有在真正需要时才应该进行系统调用

【讨论】:

    猜你喜欢
    • 2021-11-29
    • 1970-01-01
    • 2020-03-02
    • 2014-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    • 2021-08-02
    相关资源
    最近更新 更多