Why do I get nonsense from GetModuleFileNameEx on 64-bit Windows 8?

我的梦境 提交于 2019-12-09 18:36:38

问题


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:

  1. Use a separate 64 bit process, and some IPC, to retrieve the information.
  2. Use WMI to get the module file name.
  3. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!