我想知道两个Win32 API函数 EnumProcesses()和 CreateToolhelp32Snapshot()之间是否存在任何差异(主要是性能方面的差异),用于枚举所有活动进程并加载模块。或者,如果一个比另一个更好用,为什么。
答案 0 :(得分:12)
我认为它们在性能(和结果)方面几乎相同,因为它们都调用相同的底层NT API,尽管CreateToolhelp32Snapshot()可能会有轻微的开销,因为它创建了一个section对象并将所有信息复制到它与EnumProcesses()/ EnumProcessModules()直接与用户提供的缓冲区一起工作。但是,在现实世界中,差异可能是微不足道的。
我稍微喜欢EnumProcesses(),因为它(IMO)是一个更简单的API,但是如果需要,CreateToolhelp32Snapshot()会返回更多信息。 EnumProcesses()的唯一缺点是你应该在一个循环中调用它,因为你可能没有分配足够大的缓冲区; CreateToolhelp32Snapshot()负责管理缓冲区管理。在实践中,我只是在堆栈上分配一个足够大的缓冲区来容纳1024个进程ID或模块句柄;到目前为止,我还没有遇到这样一个系统,即这些限制中的任何一个甚至远远接近达到。当然,不久前我们对MAX_PATH说了同样的话,现在我们遇到了问题......
答案 1 :(得分:12)
以下是几项功能的结果:
计算机正在运行启用了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()
重写了它,我再也没有听说过任何问题。