EnumProcesses()与CreateToolhelp32Snapshot()

我想知道在两个Win32 API函数EnumProcesses()CreateToolhelp32Snapshot()之间是否存在任何差异 – 主要是性能方面的差异 – 枚举所有活动的进程和加载的模块。 或者,如果一个比另一个更好使用,为什么。

我认为它们在性能(和结果)方面几乎是一样的,因为它们都调用相同的底层NT API,尽管CreateToolhelp32Snapshot()可能会有轻微的开销,因为它会创建一个节对象并将所有信息复制到它,而EnumProcesses ()/ EnumProcessmodulees()直接与用户提供的缓冲区一起工作。 不过,真实世界的表现可能是微不足道的。

我稍微偏好EnumProcesses(),因为它是一个更简单的API使用,但CreateToolhelp32Snapshot()返回更多的信息,如果你需要它。 EnumProcesses()唯一的缺点是你应该在循环中调用它,因为你可能没有分配足够大的缓冲区; CreateToolhelp32Snapshot()负责为您进行缓冲区管理。 在实践中,我只是在栈上分配一个足够大的缓冲区来存放1024个进程ID或模块句柄; 到目前为止,我还没有遇到一个系统,其中任何一个限制甚至远远达到。 不久之前,我们对MAX_PATH也是这样说的,现在我们遇到了一些问题。

这里是几个函数的结果:

  • 枚举进程:16毫秒,207进程
  • CreateToolhelp32Snapshot:141毫秒(16毫秒),207个进程
  • WTSEnumerateProcesses:16毫秒,207个进程
  • WTSEnumerateProcessesEx(WTS_CURRENT_SESSION):16毫秒,98个进程
  • WTSEnumerateProcessesEx(WTS_ANY_SESSION):16毫秒,207个进程

计算机正在运行Windows 8并启用了UAC,用户不会升级(例如,无法访问系统进程)。 主进程是32位的,机器是64位的,所以围绕着64位进程。 有:系统的会话0,当前控制台用户的会话1,另一个快速切换用户的会话2。 总共207个进程(这些都是32位和64位,包括伪“系统”进程) – 207也被Process Explorer确认。 在这207个进程中:23个进程用于会话2,98个进程 – 用于会话1,剩余 – 用于会话0。

结果是10个单一函数调用的周期。 在每次运行中它们都是100%可重复的。

对于CreateToolhelp32Snapshot,主要结果是调用CreateToolhelp32Snapshot本身,而第二个结果(在括号中)是循环的First / Next。

我认为人们混淆了“枚举所有进程”(获得PID)和“获取进程/ exe的名称”。 第一个(“枚举”)没有x32 / x64交叉位的问题。 但后者(“获取名称”)确实存在问题 – 并非每种方法都能在x32 / x64上运行。

我不太清楚,但与CreateToolhelp32Snapshot()不同,EnumProcesses()具有以下两个或两个限制之一:1.如果在64位操作系统上从32位进程调用,则不枚举64位进程。 2.不列举Vista和Win7上的升级过程。

CreateToolhelp32Snapshot FTW。 至少在Win XP上,EnumProcesses并不像所有的svchost.exe实例那样枚举所有的系统进程。

国际海事组织关键的区别是在特权的要求。 我见过EnumProcesses()会失败的情况,但是CreateToolhelp32Snapshot()运行得很好。

所以一旦我需要编写代码来检测系统上的某个进程并做出适当的反应。 我使用EnumProcesses()编写它,它在我的机器上工作正常,但不在测试人员的机器上。 我用CreateToolhelp32Snapshot()重写了它,我从来没有听说过任何问题了。