问题
I have this
function NazwaProcesu(const uchwyt: Thandle): string;
var
pid: DWORD;
hProcess: Thandle;
sciezka: array [0..MAX_PATH - 1] of char;
begin
GetWindowThreadProcessId(uchwyt, pid);
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, pid);
if hProcess <> 0 then
try
GetModuleFileNameEx(hProcess, 0, sciezka, MAX_PATH)
finally
Result := sciezka;
CloseHandle(hProcess);
end;
end;
On windows 7 32 bit no problems. On Win 8 x64 i have this:
where last 3 entries should be explorer.exe, i guess. Thanks for help.
回答1:
As far as I am aware, this approach will fail to retrieve 64 bit process information when the code is executed in a 32 bit process. This sort of problem is common when running inside the WOW64 emulator and the cleanest way to avoid such issues is to run the code outside of the WOW64 emulator. That is, run your code in a 64 bit process.
Other possible ways to work around this, if you cannot re-compile as 64 bit are:
- Use a separate 64 bit process, and some IPC, to retrieve the information.
- Use WMI to get the module file name.
- Use
QueryFullProcessImageName
.
Another point that I always like to stress, is that error checking is important. You fail to check for errors when you call GetModuleFileNameEx
. The calls are clearly failing which is why you end up with an uninitialized text buffer. Always check Windows API calls for errors.
回答2:
After modifications:
function NazwaProcesu(const uchwyt: Thandle): string;
type
TQueryFullProcessImageName = function(hProcess: Thandle; dwFlags: DWORD; lpExeName: PChar; nSize: PDWORD): BOOL; stdcall;
var
pid: DWORD;
hProcess: Thandle;
sciezka: array [0 .. MAX_PATH - 1] of Char;
QueryFullProcessImageName: TQueryFullProcessImageName;
nSize: cardinal;
begin
Result := '';
GetWindowThreadProcessId(uchwyt, pid);
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, pid);
if hProcess <> 0 then
try
if GetModuleFileNameEX(hProcess, 0, sciezka, MAX_PATH) <> 0 then Result := sciezka
else if Win32MajorVersion >= 6 then
begin
nSize := MAX_PATH;
ZeroMemory(@sciezka, MAX_PATH);
@QueryFullProcessImageName := GetProcAddress(GetModuleHandle('kernel32'), 'QueryFullProcessImageNameW');
if Assigned(QueryFullProcessImageName) then
if QueryFullProcessImageName(hProcess, 0, sciezka, @nSize) then Result := sciezka
end;
finally
CloseHandle(hProcess);
end;
end;
来源:https://stackoverflow.com/questions/25063530/why-do-i-get-nonsense-from-getmodulefilenameex-on-64-bit-windows-8