C/C++ 获取进程完整目录

举报
微软技术分享 发表于 2022/12/24 19:45:55 2022/12/24
【摘要】 输出特定进程所在位置的完整路径,并输出路径。方法1 定位某个进程(比如 QQMusic.exe)所在的全路径,下面是代码:string GetProcessInfo(HANDLE hProcess,char* processName){ PROCESSENTRY32* pinfo = new PROCESSENTRY32; //进程信息 (pinfo->dwSize = sizeof(PRO...

输出特定进程所在位置的完整路径,并输出路径。

方法1 定位某个进程(比如 QQMusic.exe)所在的全路径,下面是代码:

string GetProcessInfo(HANDLE hProcess,char* processName)
{
	PROCESSENTRY32* pinfo = new PROCESSENTRY32; //进程信息 (pinfo->dwSize = sizeof(PROCESSENTRY32);)
	MODULEENTRY32* minfo = new MODULEENTRY32; //模块信息 (minfo->dwSize = sizeof(MODULEENTRY32);)
    char shortpath[MAX_PATH];				//保存路径变量

	int flag = Process32First(hProcess,pinfo);	// 从第一个进程开始
    while(flag){

		// 如果是 QQMusic.exe 这个进程
		if(strcmp(pinfo->szExeFile, processName) == 0){

			// 创建进程快照
			HANDLE hModule = CreateToolhelp32Snapshot(
				TH32CS_SNAPMODULE,		//(DWORD) 快照返回的对象,TH32CS_SNAPMODULE 是指 "特定进程的使用模块的列表"
				pinfo->th32ProcessID	//(DWORD) 要获取快照进程的PID,当前进程/系统列表 快照时设为0
				); 

			// 把第一个模块信息给 minfo
			Module32First(
				hModule,  //(HANDLE) CreateToolhelp32Snapshot 的返回句柄
				minfo	 // (LPMODULEENTRY32)  接收模块信息
				);    

			// 把文件路径给 shortpath
			GetShortPathName(
				minfo->szExePath,	//  文件路径(但最好不要用这个,因为这个碰到中文会出现乱码)
				shortpath,		// 用来接收 minfo->szExePath 兼容中文的值
				256			// 缓冲区大小
				); 

			return shortpath;
		}
        
		// 下一个进程
		flag = Process32Next(hProcess, pinfo);
    }

	return NULL;
}

int main()
{
	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // 创建进程快照
	PROCESSENTRY32 process = {sizeof(PROCESSENTRY32)};	// 用来接收 hProcessSnap 的信息
	
	// 遍历进程快照
	while (Process32Next(hProcessSnap,&process)){
		// 找到 QQMusic.exe 进程
		string processName = process.szExeFile; // char* 转 string
		if(processName == "QQMusic.exe"){
			string s_exePath = GetProcessInfo(hProcessSnap,"QQMusic.exe"); // 进程的全路径 
			cout << s_exePath << endl;
			break;
		}
	}
	
	return 0;
}

image.png

方法2 第一种方法有些 bug,下面说下另一种方法

另一种方法:

	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); // 创建进程快照
	PROCESSENTRY32 process = {sizeof(PROCESSENTRY32)};	// 用来接收 hProcessSnap 的信息
	
	// 遍历进程快照
	while (Process32Next(hProcessSnap,&process)){
		// 获取进程名
		string processName = process.szExeFile;
		cout << processName << endl;
		
		// 获取全路径
		char chpath[MAX_PATH];
		HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID);
		GetModuleFileNameEx(hProcess,NULL,chpath,sizeof(chpath));
		cout << chpath << endl;
		
		cout << "-------------------" << endl;
	}

但是注意,这种方法不能获取路径在 system32 的进程路径,其余正常:

image.png

方法3(推荐) 目前没有发现 Bug,无法读取应用程序拒绝访问的进程路径,其他没有问题。

// dos 文件路径转 windows 文件路径
BOOL DosPathToNtPath(LPTSTR pszDosPath, LPTSTR pszNtPath)
{
	TCHAR			szDriveStr[500];
	TCHAR			szDrive[3];
	TCHAR			szDevName[100];
	INT				cchDevName;
	INT				i;
	
	//检查参数
	if(!pszDosPath || !pszNtPath )
		return FALSE;
 
	//获取本地磁盘字符串
	if(GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr))
	{
		for(i = 0; szDriveStr[i]; i += 4)
		{
			if(!lstrcmpi(&(szDriveStr[i]), _T("A:\\")) || !lstrcmpi(&(szDriveStr[i]), _T("B:\\"))){continue;}

			szDrive[0] = szDriveStr[i];
			szDrive[1] = szDriveStr[i + 1];
			szDrive[2] = '\0';
			// 查询 Dos 设备名
			if(!QueryDosDevice(szDrive, szDevName, 100)){return FALSE;}
				
			// 命中
			cchDevName = lstrlen(szDevName);
			if(_tcsnicmp(pszDosPath, szDevName, cchDevName) == 0){
				// 复制驱动器
				lstrcpy(pszNtPath, szDrive);

				// 复制路径
				lstrcat(pszNtPath, pszDosPath + cchDevName);
 
				return TRUE;
			}			
		}
	}
 
	lstrcpy(pszNtPath, pszDosPath);
	
	return FALSE;
}

// 获取进程全路径
BOOL GetProcessFullPath(DWORD dwPID,string &fullPath){
	TCHAR		szImagePath[MAX_PATH];
	TCHAR		pszFullPath[MAX_PATH];
	HANDLE		hProcess;
	
	// 初始化失败
	if(!pszFullPath){return FALSE;}
	pszFullPath[0] = '\0';

	// 获取进程句柄失败
	hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwPID);
	if(!hProcess){return FALSE;}
		
	// 获取进程完整路径失败
	if(!GetProcessImageFileName(
		hProcess,					// 进程句柄
		szImagePath,				// 接收进程所属文件全路径的指针
		MAX_PATH					// 缓冲区大小
	)){
		CloseHandle(hProcess);
		return FALSE;
	}
 
	// 路径转换失败
	if(!DosPathToNtPath(szImagePath, pszFullPath)){
		CloseHandle(hProcess);
		return FALSE;
	}
 
	CloseHandle(hProcess);
 
	// 导出文件全路径
	fullPath = pszFullPath;

	return TRUE;
}

调用例子:

tring str_filePath;
GetProcessFullPath(进程ID,str_filePath);
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。