How can I retrieve a process's fully-qualified path from its PID using C++ on Windows?
5 Answers
Call OpenProcess
to get a handle to the process associated with your PID. Once you have a handle to the process, call GetModuleFileNameEx
to get its fully-qualified path. Don't forget to call CloseHandle
when you're finished using the process handle.
Here's a sample program that performs the required calls (replace 1234 with your PID):
#include <windows.h>
#include <psapi.h> // For access to GetModuleFileNameEx
#include <tchar.h>
#include <iostream>
using namespace std;
#ifdef _UNICODE
#define tcout wcout
#define tcerr wcerr
#else
#define tcout cout
#define tcerr cerr
#endif
int _tmain(int argc, TCHAR * argv[])
{
HANDLE processHandle = NULL;
TCHAR filename[MAX_PATH];
processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, 1234);
if (processHandle != NULL) {
if (GetModuleFileNameEx(processHandle, NULL, filename, MAX_PATH) == 0) {
tcerr << "Failed to get module filename." << endl;
} else {
tcout << "Module filename is: " << filename << endl;
}
CloseHandle(processHandle);
} else {
tcerr << "Failed to open process." << endl;
}
return 0;
}

- 6,706
- 3
- 32
- 39
-
2most of modules turn to a failure in getting file path :( – jondinham Aug 29 '11 at 04:20
-
4Does it work when called from a 32bit environemet to get PID of a 64bit process ? I face problem and had to use **QueryFullProcessImageName** instead of **GetModuleFileNameEx** – philippe lhardy Nov 13 '14 at 17:55
I didn't have very much luck with GetModuleFileNameEx and QueryFullProcessImageName is only available on Vista or higher. I was however able to get the path for a process by using GetProcessImageFilename. It returns the windows kernel path but you can use QueryDosDevice to compare the device path returned by GetProcessImageFilename
with its proper drive path.
This page shows how to normalize an windows kernel path returned by GetProcessImageFilename
(see NormalizeNTPath
function):
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/c48bcfb3-5326-479b-8c95-81dc742292ab/

- 5,506
- 4
- 29
- 30
-
2See http://stackoverflow.com/questions/696306/run-time-check-failure-0-loading-queryfullprocessimagename-from-kernel32-dll#696365 on how to define **QueryFullProcessImageName** API call even if your SDK is not supporting it. – philippe lhardy Nov 13 '14 at 17:59
-
QueryFullProcessImageName is not available in XP which is what I was targeting. – Nathan Moinvaziri Jan 05 '20 at 20:41
Some notes to Emerick Rogul's solution:
Don't forget to add 'psapi.lib' to linker (additional dependencies).
I also changed PROCESS_ALL_ACCESS
to PROCESS_QUERY_INFORMATION | PROCESS_VM_READ
because I got:
Failed to open process.
If it's compiled as a 32 bit application it will fail to get the name of 64 bit processes ("Failed to get module filename.")

- 3,662
- 5
- 30
- 34

- 378
- 2
- 11
Sometimes GetModuleFileNameEx
returns the 299 error code (I don't know why)
The only method that works for all versions of Windows, including XP is in Nathan Moinvaziri answer:
check the provided url:
-
Perhaps match my comment, from a 32bit process i fear it might fail to get path of a 64bit process. I had to use **QueryFullProcessImageName** instead of **GetModuleFileNameEx** – philippe lhardy Nov 13 '14 at 17:57
Have you tried QueryFullProcessImageName
?