C++ EnumProcesses()与CreateToolhelp32Snapshot()的比较
我想知道枚举所有活动进程和加载模块的两个Win32 API函数EnumProcesses()和CreateToolhelp32Snapshot()之间是否存在任何差异(主要是性能方面的差异)。或者如果一个比另一个更好使用,以及为什么。在我看来,关键区别在于特权要求。我见过C++ EnumProcesses()与CreateToolhelp32Snapshot()的比较,c++,c,windows,winapi,C++,C,Windows,Winapi,我想知道枚举所有活动进程和加载模块的两个Win32 API函数EnumProcesses()和CreateToolhelp32Snapshot()之间是否存在任何差异(主要是性能方面的差异)。或者如果一个比另一个更好使用,以及为什么。在我看来,关键区别在于特权要求。我见过enumprocess()失败的例子,但是CreateToolhelp32Snapshot()运行得非常好 所以有一次我需要编写代码来检测系统上的某个进程并做出适当的反应。我使用enumprocess()编写了它,它在我的机器上
enumprocess()
失败的例子,但是CreateToolhelp32Snapshot()
运行得非常好
所以有一次我需要编写代码来检测系统上的某个进程并做出适当的反应。我使用
enumprocess()
编写了它,它在我的机器上运行良好,但在测试人员的机器上运行不好。我只是用CreateToolhelp32Snapshot()
重写了它,我再也没有听说过它有任何问题。我认为它们在性能(和结果)方面几乎相同,因为它们都调用相同的底层NT API,尽管CreateToolhelp32Snapshot()可能会有轻微的开销,因为它会创建一个section对象并将所有信息复制到该对象,而enumProcesss()/EnumProcessModules()直接使用用户提供的缓冲区。不过,在现实世界中,这种差异可能可以忽略不计
我稍微喜欢EnumProcesses(),因为它(IMO)是一个更简单的API,但CreateToolhelp32Snapshot()会在需要时返回更多信息。EnumProcesses()唯一的缺点是您应该在循环中调用它,因为您可能没有分配足够大的缓冲区;CreateToolhelp32Snapshot()负责为您管理缓冲区。实际上,我只是在堆栈上分配一个足够大的缓冲区来容纳1024个进程ID或模块句柄;到目前为止,我还没有遇到一个系统,其中任何一个极限都几乎达到。当然,不久前我们对MAX_PATH也说过同样的话,现在我们遇到了问题…我记不清了,但与CreateToolhelp32Snapshot()不同,EnumProcess()有两个或两个限制之一: 1.如果从x64操作系统上的32位进程调用,则不枚举64位进程。
2.不枚举Vista和Win7上提升的进程 CreateToolhelp32Snapshot FTW。
EnumProcesss不会枚举所有系统进程,例如至少在Win XP上的svchost.exe的所有实例。以下是几个函数的结果:
- 枚举进程:16毫秒,207个进程
- CreateToolhelp32Snapshot:141毫秒(16毫秒),207个进程
- WTSEnumerate进程:16毫秒,207个进程
- WTSEnumerateProcessEx(WTS_当前_会话):16毫秒,98个进程
- WTSEnumerateProcessEx(WTS_任意会话):16毫秒,207个进程
我认为人们混淆了“枚举所有进程”(获取PID)和“获取进程名/exe”。第一个(“枚举”)与x32/x64交叉位没有任何问题。但后一种方法(“get name”)确实存在问题-并非每个方法都能在x32/x64上工作。上次我查看EnumProcesses()和CreateToolhelp32Snapshot()时,它们都调用了相同的底层NT API(NtQuerySystemInformation),所以我不确定如何得到不同的结果。实际上调用
EnumProcesses()
在循环中不是问题。只需使用std::vector
来管理缓冲区生存期。啊,所以它们确实调用了相同的底层API。这就是我想知道的。谢谢。“足够大,可以容纳1024个进程ID”-在终端服务/远程桌面机器上很容易耗尽,为30个用户提供服务,每个用户有40个进程。为了有效利用EnumProcess,很可能需要打开每个进程并查询信息。如果请求PROCESS\u QUERY\u信息和PROCESS\u VM\u READ(这是GetModuleBaseName所必需的),则某些进程将失败。为了避免Dmitry的回答中提到的限制,可以使用PROCESS\u QUERY\u LIMITED\u信息打开,并使用GetProcessImageFileName(在旧版本的Windows上除外)。