[Solved] Windows - getting path of 64 bit process from 32 bit application
-
wrote on 20 Nov 2012, 09:07 last edited by
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.
-
wrote on 20 Nov 2012, 10:55 last edited by
Have you tried disabling the WoW64 filesystem redirection ?
See "here":http://goo.gl/ggICD -
wrote on 20 Nov 2012, 12:00 last edited by
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.
-
wrote on 20 Nov 2012, 12:46 last edited by
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
2/4