[Win32] 获取进程完整路径

来源:互联网 发布:双十一数据图 编辑:程序博客网 时间:2024/05/18 14:45

本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处:http://blog.csdn.net/zuishikonghuan/article/details/47746621

上两篇中,我们讲到了ToolHelp API,Process API和提升Debug权限,这一篇中来说说如何获取进程的程序路径。

获取进程路径其实有很多方法。

方法1。使用ToolHelp API枚举模块,其中,Module32First得到一个MODULEENTRY32 结构,结构中有一个szExePath成员,这个成员代表这个进程第一个模块的路径,也就是进程的路径

(32位程序只能获取32位程序路径,64位程序可以获取32位和64位程序路径,但需要把TH32CS_SNAPMODULE换成TH32CS_SNAPMODULE32)

方法2。使用OpenProcess打开进程,需要具有PROCESS_QUERY_INFORMATION 和 PROCESS_VM_READ权限,然后用EnumProcessModules获取第一个模块的模块句柄,之后用GetModuleFileNameEx获取模块路径。

EnumProcessModules的模块句柄无需释放:Do not call CloseHandle on any of the handles returned by this function. The information comes from a snapshot, so there are no resources to be freed.

(32位程序只能获取32位程序路径,64位程序只能获取64位程序路径)

完整源码:

#define PSAPI_VERSION 1#include <psapi.h> #pragma comment(lib,"psapi.lib")

// 获取进程路径 参数1:进程ID 参数2:缓冲区指针,接收路径void GetProcessPath(DWORD dwProcessID, LPCTSTR buffer){TCHAR Filename[MAX_PATH];HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID);if (hProcess == NULL)return;HMODULE hModule;DWORD cbNeeded;if (EnumProcessModules(hProcess, &hModule, sizeof(hModule), &cbNeeded)){if (GetModuleFileNameEx(hProcess, hModule, Filename, MAX_PATH)){RtlMoveMemory((void*)buffer, Filename, sizeof(TCHAR)*MAX_PATH);}}CloseHandle(hProcess);}

方法3。使用GetProcessImageFileName,可以在32位程序中获取32位和64位进程路径,这个可以在xp和以后系统中用,但是取得的进程路径是设备名路径,所以还需要遍历磁盘驱动器转换成我们需要的路径,比较麻烦。

方法4。使用QueryFullProcessImageName,可以在32位程序中获取32位和64位进程路径,同时这也是微软提供的32位程序获取64位进程路径的正确方法,缺点是只能在Vista以后的系统中用

BOOL WINAPI QueryFullProcessImageName(  _In_    HANDLE hProcess,  _In_    DWORD  dwFlags,  _Out_   LPTSTR lpExeName,  _Inout_ PDWORD lpdwSize);

hProcess:进程句柄,需要具有PROCESS_QUERY_INFORMATION或者PROCESS_QUERY_LIMITED_INFORMATION权限

dwFlags:以下值

0:名称应使用 Win32 路径格式。

PROCESS_NAME_NATIVE:名称应使用原生系统路径格式

lpExeName:缓冲区指针,用于接收可执行映像的路径

lpdwSize:以字符为单位指定缓冲区大小的 lpExeName,不包括空终止字符的数

返回值:如果此函数成功,返回值不为零。如果函数失败,返回值为零。

不过感觉这个函数忒难用,,那么加上这个函数,GetModuleFileNameEx获取不了的就用QueryFullProcessImageName,那么GetProcessPath就成这样的了:

// 获取进程路径 参数1:进程ID 参数2:缓冲区指针,接收路径void GetProcessPath(DWORD dwProcessID, LPCTSTR buffer){TCHAR Filename[MAX_PATH];HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID);if (hProcess == NULL)return;HMODULE hModule;DWORD cbNeeded;if (EnumProcessModules(hProcess, &hModule, sizeof(hModule), &cbNeeded)){if (GetModuleFileNameEx(hProcess, hModule, Filename, MAX_PATH)){RtlMoveMemory((void*)buffer, Filename, sizeof(TCHAR)*MAX_PATH);}}else{DWORD size = MAX_PATH;if (QueryFullProcessImageName(hProcess, 0, Filename, &size)){RtlMoveMemory((void*)buffer, Filename, sizeof(TCHAR)*MAX_PATH);}}CloseHandle(hProcess);}

这样绝大部分进程都可以获取路径了,有几个系统进程(比如services.exe)进程即使以Debug也无法打开获取句柄,因此无法获取路径


0 0
原创粉丝点击