转载自: http://blog.csdn.net/hellokandy/article/details/52160077
通过进程句柄,获得可执行文件的路径,主要有以下几种方法:
第一种方法:也是最常用的方法,是通过GetModuleFileNameEx函数获得可执行文件的模块路径,这个函数从Windows NT 4.0开始到现在的Vista系统都能使用,向后兼容性比较好。
【函数原型】调用失败将返回0。注:进程的句柄须有PROCESS_QUERY_INFORMATION 和 PROCESS_VM_READ权限。
- DWORD
- WINAPI
- GetModuleFileNameExW(
- __in HANDLE hProcess,
- __in_opt HMODULE hModule,
- __out_ecount(nSize) LPWSTR lpFilename,
- __in DWORD nSize
- );
GetModuleFileNameEx 的使用例子:
- #include <Psapi.h>
- #pragma comment (lib,"Psapi.lib")
-
- HANDLE h_Process=OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,ProcessID);
- wchar_t path[MAX_PATH+1];
- if(!GetModuleFileNameEx(h_Process,NULL,path,MAX_PATH+1))
- return false;
-
注意:GetModuleFileNameEx函数在64位系统下,获取不到64位进程的可执行文件路径。
第二种方法:GetProcessImageFileName函数,这个函数在Windows XP及其以后的系统中都能使用,使用此函数返回的路径不是通常的系统盘符,如"C:\...",而是驱动层的表示方式"\Device\HarddiskVolume1\...",所以使用起来不是很方便。
【函数原型】函数失败将返回0。注:进程句柄需要有PROCESS_QUERY_INFORMATION的权限。
- DWORD
- WINAPI
- GetProcessImageFileNameW (
- __in HANDLE hProcess,
- __out_ecount(nSize) LPWSTR lpImageFileName,
- __in DWORD nSize
- );
注意:调用 GetModuleFileNameEx 和 GetProcessImageFileName 需要包含Psapi.h头文件,并链接到Psapi.lib。
第三种方法:使用Windows Vista新增的函数QueryFullProcessImageName,由于是Vista新增的,所以兼容性不好。
【函数原型】函数失败将返回FALSE。
- BOOL
- WINAPI
- QueryFullProcessImageNameW(
- __in HANDLE hProcess,
- __in DWORD dwFlags,
- __out_ecount_part(*lpdwSize, *lpdwSize) LPWSTR lpExeName,
- __inout PDWORD lpdwSize
- );
dwFlags,如将其设为PROCESS_NAME_NATIVE将返回"\Device\HarddiskVolume1\..."这样的格式路径。调用此函数的句柄须有PROCESS_QUERY_INFORMATION 或 PROCESS_QUERY_LIMITED_INFORMATION 的权限,并且只能在Vista或更高版本的系统中使用。
第四种方法:其实也是最靠谱的方法!使用GetProcessImageFileName ,不过该函数返回的格式是DOS格式,需要再通过与 LogicalDriveStrings 比对拼接出进程可执行文件的完整路径。方法如下:
-
-
-
-
-
- bool GetProcessFilePath(IN HANDLE hProcess, OUT std::wstring& szFilePath)
- {
- szFilePath = _T("");
- TCHAR tsFileDosPath[MAX_PATH + 1];
- ZeroMemory(tsFileDosPath, sizeof(TCHAR)*(MAX_PATH + 1));
- if (0 == GetProcessImageFileName(hProcess, tsFileDosPath, MAX_PATH + 1))
- {
- return false;
- }
-
-
- UINT uiLen = GetLogicalDriveStrings(0, NULL);
- if (0 == uiLen)
- {
- return false;
- }
-
- PTSTR pLogicDriveString = new TCHAR[uiLen + 1];
- ZeroMemory(pLogicDriveString, uiLen + 1);
- uiLen = GetLogicalDriveStrings(uiLen, pLogicDriveString);
- if (0 == uiLen)
- {
- delete[]pLogicDriveString;
- return false;
- }
-
- TCHAR szDrive[3] = TEXT(" :");
- PTSTR pDosDriveName = new TCHAR[MAX_PATH];
- PTSTR pLogicIndex = pLogicDriveString;
-
- do
- {
- szDrive[0] = *pLogicIndex;
- uiLen = QueryDosDevice(szDrive, pDosDriveName, MAX_PATH);
- if (0 == uiLen)
- {
- if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
- {
- break;
- }
-
- delete[]pDosDriveName;
- pDosDriveName = new TCHAR[uiLen + 1];
- uiLen = QueryDosDevice(szDrive, pDosDriveName, uiLen + 1);
- if (0 == uiLen)
- {
- break;
- }
- }
-
- uiLen = _tcslen(pDosDriveName);
- if (0 == _tcsnicmp(tsFileDosPath, pDosDriveName, uiLen))
- {
- wchar_t buf[1024];
- swprintf_s(buf, 1024, L"%s%s", szDrive, tsFileDosPath + uiLen);
- wchar_t *pstr = buf;
- szFilePath = std::wstring(pstr);
-
- break;
- }
-
- while (*pLogicIndex++);
- } while (*pLogicIndex);
-
- delete[]pLogicDriveString;
- delete[]pDosDriveName;
-
- return true;
- }
所有评论(0)