如何可靠地检查一个Windows进程是否是C ++中另一个进程的父进程?

时间:2011-07-06 07:36:01

标签: c++ windows winapi

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

DWORD getParentPid( DWORD pid );

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

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

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

这个问题在于它非常依赖于严格单调的系统时钟和GetProcessTimes的粒度。我确实遇到过CompareFileTime返回0(意思是“平等时间”)的情况,即使正在考虑的过程确实处于亲子关系中。我可以更改我的检查,以便CompareFileTime结果值<= 0将被视为表示父项,但是我会打破(理论上)父项创建子进程的情况,然后父进程是销毁,然后Windows重新使用PID - 全部在100ns内(这是GetProcessTimes的分辨率。)

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

编辑:我需要此功能才能确定所有子进程(这意味着包括祖子进程)。 CompareFileTime允许我遍历所有进程,但我需要查看每个进程的父PID,以判断它是否是我手边进程的子进程。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

此处的示例:

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

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