【问题标题】:How can I reliably check whether one Windows process is the parent of another in C++?如何可靠地检查一个 Windows 进程是否是 C++ 中另一个 Windows 进程的父进程?
【发布时间】:2011-07-06 07:36:01
【问题描述】:

我正在开发一个函数,它可以让我获得给定 PID 的父进程的 PID。该函数的原型是

DWORD getParentPid( DWORD pid );

为此,我使用CreateToolhelp32Snapshot 函数(和相关函数)来获取给定PID pidPROCESSENTRY32 结构。然后我可以使用结构的th32ParentProcessId 字段来获取创建给定进程的进程的PID。

但是,由于父进程可能已经被销毁(并且它的 PID 可能已被 Windows 重用),我使用GetProcessTimes 函数来获取假定的父进程和子进程的创建时间,然后比较那些使用CompareFileTime的。

如果CompareFileTime返回-1,我知道父ID的进程是在我的子进程之前创建的,所以它确实是父进程。否则,它显然是一个重复使用的 ID - 并且父 PID 无效(它不再引用原始父)。

问题在于它非常依赖严格单调的系统时钟和GetProcessTimes 的粒度。我确实遇到过CompareFileTime 返回0(意思是“相等的时间”)的案例,尽管所考虑的过程确实是亲子关系。我可以更改我的检查,以便将 CompareFileTime 结果值 <= 0 视为指示父进程,但随后我将打破父进程创建子进程,然后父进程被销毁,然后Windows 重新使用了 PID - 都在 100ns 内(这是GetProcessTimes 的分辨率)。

我想知道 - 是否有不同的、更可靠的机制来验证某个进程确实是 C++ 中另一个进程的父进程?

编辑:我需要这个函数来确定所有子进程(这意味着包括孙子进程)。 CreateToolhelp32Snapshot 让我可以遍历所有进程,但我需要查看每个进程的父 PID,以判断它是否是我手头进程的子进程。

【问题讨论】:

  • 并非如此。但是你为什么需要这个?如果您甚至不知道父进程是否仍在运行,即使可以可靠地识别它,您会如何处理它?听起来像是寻找问题的解决方案。
  • @jalf:我编辑了我的问题以提供更多背景信息。
  • 这不是上下文。您只是在解释您正在尝试做的任何事情的下一步。因此,如果我问您“为什么需要确定所有子进程”...? ;) 如果您甚至不知道父进程是否仍在运行,那么很难看出确定的父/子会实现什么。
  • @jalf:我试图在 GUI 中显示一个进程树(或者,可选地,进程树的一个子集)。如果这也不是上下文,则这是用于监视失控进程的应用程序的一部分。如果这还不够上下文,那么它适用于想要调试正在运行的进程的客户(这往往会跑掉,在这种情况下,他可能想要也可能不想杀死整个进程树,有点像 Process Explorer)。
  • 无法判断一个进程是否由另一个特定进程创建。您所指的“th32ParentProcessId”字段实际上在内核EPROCESS结构中称为“InheritedFromUniqueProcessId”,它表示继承属性的进程。虽然大多数时候它确实表明了哪个进程创建了子进程,但这根本不能保证。

标签: c++ windows winapi


【解决方案1】:

如果在您的应用程序运行时创建了进程,您可以随着时间的推移反复迭代它并捕获 PID 重用。

【讨论】:

    【解决方案2】:

    这里的示例:

    http://msdn.microsoft.com/en-us/library/ms686701(v=vs.85).aspx

    显示调用 CreateToolhelp32Snapshot,processId 的参数为 0,它使用选项 TH32CS_SNAPPROCESS 表示它捕获所有进程。然后,一旦您获得了快照,就像在示例中一样,您可以按照快照中存在的流程进行处理。父 ID 在快照中应该是有效的,因为您正在查看所有进程的状态,因为它们存在于拍摄快照的那一刻。您不必费心处理流程开始时间比较的东西。

    【讨论】:

    • 无法保证在拍摄快照时父进程存在。它本可以提前一个小时终止。
    • 这是我的第一次尝试,在我使用GetProcessTimes 改进检测之前,如我的问题中所写。 jalf 写的正是我要解决的问题。
    • 好的。一个有趣的讨论,如果你还没有看过:sapphiresteel.com/Blog/Killing-Trees-the-Windows-way
    • @Scott:这篇文章非常有趣,感谢分享!
    • 接受这个答案,因为在 Scott 发布的链接中有一条评论建议使用 WMI 来侦听进程创建/销毁事件并维护映射。听起来它实际上可以可靠地工作。
    猜你喜欢
    • 1970-01-01
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多