Reputation: 19837
I was wondering if there are any differences - mostly performance wise - between the two Win32 API functions EnumProcesses() and CreateToolhelp32Snapshot() for enumerating all active processes and loaded modules. Or if one is better than the other to use and why.
Upvotes: 31
Views: 23699
Reputation: 5668
Here are results from few functions:
Machine is running Windows 8 with UAC enabled, user is not elevated (e.g. have no access to system processes). Main process is 32-bit, machine is 64-bit, so plenty of 64-bit processes around. There are: session 0 for system, session 1 for current console user, session 2 for another fast-switch user. 207 processes in total (these are both 32- and 64-bit, including pseudo "system" process) - 207 is also confirmed by Process Explorer. Among these 207 processes: 23 processes are for session 2, 98 processes - for session 1, and remaining - for session 0.
Results are for cycle of 10 single function call. They are 100% reproducible on each run.
For CreateToolhelp32Snapshot the main result is call of CreateToolhelp32Snapshot itself, and second result (in brackets) is cycle with First/Next.
I think people confuse "enumerate all processes" (get PIDs) and "get name of process/exe". The first one ("enumerate") has no issues with x32/x64 cross-bitness whatsoever. But the latter one ("get name") does have issues - not every method will work across x32/x64.
Upvotes: 24
Reputation: 59
CreateToolhelp32Snapshot FTW. EnumProcesses doesnt enumerate all system processes like all instances of svchost.exe at least on Win XP.
Upvotes: 5
Reputation: 69
I don’t remember exactly, but unlike CreateToolhelp32Snapshot(), EnumProcesses() has one of two or both limitations: 1. Doesn’t enumerate 64-bit processes if called from 32-bit process on x64 OS. 2. Doesn’t enumerate elevated processes on Vista and Win7.
Upvotes: 6
Reputation: 11421
I think they are pretty much the same in terms of performance (and results) as they both call the same underlying NT API, though CreateToolhelp32Snapshot() may have a slight overhead as it creates a section object and copies all the information to it whereas EnumProcesses()/EnumProcessModules() works directly with user-supplied buffers. The difference is probably negligible in real world performance, though.
I slightly prefer EnumProcesses() as it is (IMO) a simpler API to use, but CreateToolhelp32Snapshot() returns more information if you need it. The only downside to EnumProcesses() is that you are supposed to call it in a loop as you may not have allocated a large enough buffer; CreateToolhelp32Snapshot() takes care of the buffer management for you. In practice I just allocate a buffer on the stack large enough to hold 1024 process ids or module handles; so far I have not come across a system where either of these limits was even remotely close to being reached. Of course we said the same thing about MAX_PATH not so long ago and now we are running into problems with that...
Upvotes: 21
Reputation: 170509
IMO the key difference is in priviledges requirements. I've seen cases in which EnumProcesses()
would fail, but CreateToolhelp32Snapshot()
ran perfectly well.
So once I needed to write code that would detect a certain process on a system and react appropriately. I wrote it using EnumProcesses()
and it worked fine on my machine, but not on testers' machines. I just rewrote it with CreateToolhelp32Snapshot()
and I've never heard of any problems with it anymore.
Upvotes: 2