I just tried to revoke some old code from Windows XP which generates a list of all running processes, but it failed on Windows 7. Before I continue, here's the code:
#include <windows.h>
#include <tlhelp32.h>
in开发者_JS百科t main()
{
HANDLE hSnap, hTemp;
PROCESSENTRY32 pe;
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(Process32First(hSnap, &pe)) {
do {
...
}
} while(Process32Next(hSnap, &pe));
}
...
}
I checked which function failed and it turned out that it's Process32First. GetLastError() returned 24: "ERROR_BAD_LENGTH" I can't really figure out what the problem is. Any suggestions?
From MSDN: http://msdn.microsoft.com/en-us/library/ms684834(VS.85).aspx
The calling application must set the dwSize member of PROCESSENTRY32 to the size, in bytes, of the structure.
To retrieve information about other processes recorded in the same snapshot, use the Process32Next function.
EDIT: You'd probably want to do something like this:
PROCESSENTRY32 pe = {0};
pe.dwSize = sizeof(PROCESSENTRY32);
There's a bug in tlhelp32.h
, when invoked in WIN64
:
If there's a #pragma
pack directive somewhere before including tlhelp32.h
, it will generate a PROCESSENTRY32
structure with the wrong size.
Then anything can happen, including Process32First
failures, or even crashes.
Try including tlhelp32.h
this way:
#pragma pack(push,8) /* Work around a bug in tlhelp32.h in WIN64, which generates the wrong structure if packing has been changed */<br/>
#include <tlhelp32.h><br/>
#pragma pack(pop)
As jglouie answered, the problem is in missed pe.dwSize
initialization. As Jean-François Larvoire answered, even if you correctly initialize it, it can still not work due to wrong alignment when including SDK headers. He wrote about 8 bytes alignment, but according to this: the C/C++ headers in the Windows SDK assume the platform's default alignment is used
. The default alignment differs between different platforms. For example it's 8 bytes for x86 and 16 bytes for x64 (see the above link for a detailed list).
The solution is to set the default
alignment in your project settings and don't use pragma pack
for SDK headers.
Theoretically you can use constructs like this:
#ifdef _WIN64
#pragma pack(push,16)
#elif _WIN32
#pragma pack(push,8)
#else
#error Unsupported platform
#endif
include sdk here
#pragma pack(pop)
But these can not work - I encountered a case where including afxwin.h
, one of MFC headers, changed alignment to the value from project settings, thus all SDK headers included below it used the wrong alignment.
精彩评论