EnumProcesses()vs CreateToolhelp32Snapshot()

时间:2010-10-26 06:47:50

标签: c++ c windows winapi

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

5 个答案:

答案 0 :(得分:12)

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

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

答案 1 :(得分:12)

以下是几项功能的结果:

  • EnumProcesses:16毫秒,207个进程
  • CreateToolhelp32Snapshot:141毫秒(16毫秒),207个处理
  • WTSEnumerateProcesses:16毫秒,207个进程
  • WTSEnumerateProcessesEx(WTS_CURRENT_SESSION):16毫秒,98个进程
  • WTSEnumerateProcessesEx(WTS_ANY_SESSION):16毫秒,207个进程

计算机正在运行启用了UAC的Windows 8,用户未升级(例如,无法访问系统进程)。主进程是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。

答案 2 :(得分:4)

我不记得确切,但与CreateToolhelp32Snapshot()不同,EnumProcesses()具有以下两个或两个限制之一:  1.如果在x64 OS上从32位进程调用,则不枚举64位进程。  2.不列举Vista和Win7上升级的进程。

答案 3 :(得分:3)

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

答案 4 :(得分:0)

IMO的关键区别在于特权要求。我见过EnumProcesses()失败的情况,但CreateToolhelp32Snapshot()运行良好。

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