views:

54

answers:

2

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.

A: 

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.

sharptooth
Last time I looked EnumProcesses() and CreateToolhelp32Snapshot() both called the same underlying NT API (NtQuerySystemInformation) so I'm not sure how you would get different results.
Luke
+1  A: 

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...

Luke
Actually calling `EnumProcesses()` in a loop is not that of a problem. Just use `std::vector<BYTE>` for managing the buffer lifetime.
sharptooth
Ah, so they do call the same underlying API. That's mostly covers what I wanted to know. Thanks.
jay.lee