[Solved] Windows - getting path of 64 bit process from 32 bit application



  • It seems like getting the path for a 64 bit process form a 32 bit application is not possible with GetModuleFileName or GetModuleBaseName.

    The process handle is retrieved using the following code
    @DWORD pidwin;
    GetWindowThreadProcessId(foregroundWindow, &pidwin);
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pidwin);
    @
    and the following works for for getting the filename of 32 bit processes
    @TCHAR szProcessName[MAX_PATH];
    int len = GetModuleBaseName(hProcess, NULL, szProcessName, MAX_PATH);
    QString processName = QString::fromUtf16((ushort*)szProcessName, len);@

    The recommended solution seems to be to use GetProcessImageFileName or QueryFullProcessImageName, but when trying to call these methods I get the error: 'QueryFullProcessImageName' was not declared in this scope.

    Advice on how to solve this would be greatly appreciated.



  • Have you tried disabling the WoW64 filesystem redirection ?
    See "here":http://goo.gl/ggICD



  • As far as I know, this simply is a limitation of GetModuleBaseName(). You either have to call it from a 64-Bit application (which you could run as a child of your "main" 32-Bit app) or you have to use another API.

    As for QueryFullProcessImageName(), which handles 64-Bit processes fine: It was introduced with Vista, so it isn't supported on older Windows versions. Your Windows SDK probably is too old to offer that function. You can upgrad to a newer Windows SDK and then use the function, but then your app won't work on older Systems than Vista (e.g. Windows XP won't work!), of course. Therefore you might want to use LoadLibrary() + GetProcAddress() instead: Use QueryFullProcessImageName() if available, fall back to GetModuleBaseName() otherwise.



  • Thanks rcari and MulderR. The LoadLibrary / GetProcAddress approach works well. Using QLibrary the working code looks like
    [code]
    // get process handle
    DWORD pidwin;
    GetWindowThreadProcessId(foregroundWindow, &pidwin);
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pidwin);

    // get process path
    WCHAR szProcessPath[MAX_PATH];
    DWORD bufSize = MAX_PATH;
    QueryFullProcessImageName pQueryFullProcessImageName = NULL;
    pQueryFullProcessImageName = (QueryFullProcessImageName) QLibrary::resolve("kernel32", "QueryFullProcessImageNameW");
    QString processPath;
    if(pQueryFullProcessImageName != NULL) {
    pQueryFullProcessImageName(hProcess, 0, (LPWSTR) &szProcessPath, &bufSize);
    processPath = QString::fromUtf16((ushort*)szProcessPath, bufSize);
    }
    [/code]

    More information on which function to use for the different windows versions - http://msdn.microsoft.com/en-us/library/windows/desktop/ms684919(v=vs.85).aspx


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.