如何在Visual C++中通过WinAPI获取窗口对应程序的可执行文件路径?
解决方案
你的问题出在GetModuleFileName的用法上:当第一个参数传NULL时,它返回的是当前进程的可执行文件路径,而非目标窗口所属进程的路径。要获取窗口对应程序的路径,需要按以下步骤操作:
核心步骤
- 通过
GetWindowThreadProcessId从窗口句柄(HWND)获取对应的进程ID(PID) - 用
OpenProcess打开目标进程,获取进程句柄 - 调用
GetModuleFileNameEx通过进程句柄获取可执行文件路径 - 释放资源(关闭进程句柄)并完成字符串转换
修正后的函数实现
#include <windows.h> #include <psapi.h> #include <string> #include <vector> // 链接Psapi库,也可以在项目设置中添加链接依赖 #pragma comment(lib, "Psapi.lib") std::string GetWindowExe(HWND hWnd) { DWORD processId = 0; // 获取窗口所属进程的PID GetWindowThreadProcessId(hWnd, &processId); if (processId == 0) { return ""; } // 打开进程,需要足够的权限 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId); if (hProcess == NULL) { return ""; } // 获取可执行文件路径 std::vector<wchar_t> pathBuffer(MAX_PATH); DWORD pathLength = GetModuleFileNameExW(hProcess, NULL, pathBuffer.data(), static_cast<DWORD>(pathBuffer.size())); std::string exePath; if (pathLength > 0) { // 从宽字符串转换为窄字符串 exePath.assign(pathBuffer.begin(), pathBuffer.begin() + pathLength); } // 关闭进程句柄,避免资源泄漏 CloseHandle(hProcess); return exePath; }
关键说明
- 必须包含
<psapi.h>头文件,并链接Psapi.lib(通过#pragma comment或项目设置) OpenProcess需要的权限:PROCESS_QUERY_INFORMATION用于查询进程信息,PROCESS_VM_READ用于读取进程内存- 使用
GetModuleFileNameExW(宽字符版本)避免编码问题,再转换为std::string保持和原函数一致的返回类型 - 错误处理:如果获取PID、打开进程或获取路径失败,返回空字符串,你可以根据需求调整错误提示
测试验证
当你枚举窗口时调用这个修正后的函数,就能输出正确的目标程序路径,符合你期望的格式:
Untitled - Notepad Handle: 000000000006118C Path: C:\Windows\System32\notepad.exe Mozilla Firefox Handle: 00000000001C02E8 Path: C:\Program Files\Mozilla Firefox\firefox.exe
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

