总结一下,我需要这样做:
12345(hWnd) - > “C:\ SETUP.EXE”
现在,我正在使用GetProcessImageFileName
来检索进程句柄的内核设备路径。我正在使用OpenProcess
检索句柄,并将PID传递给它。我正在使用GetWindowThreadProcessId
检索PID(我也需要)。
然而,这让我得到一个像:
这样的字符串\设备\ Harddisk1的\ SETUP.EXE
此时,我使用DriveInfo.GetDrives()
枚举系统上的所有驱动器,然后调用QueryDosDevice
。最后,我可以做一些字符串操作魔法,并且“繁荣”,我有自己的道路。
QueryFullProcessImageName
有一个更好的方法来做到这一点。请赐教,哦,WIN32API的众神!
答案 0 :(得分:2)
显而易见的问题是,为什么你不只是使用QueryFullProcessImageName
,如果这是你想要的?您是否需要与旧版Windows兼容?
在XP上可用的QueryFullProcessImageName
最接近的等价物可能是GetModuleFileNameEx
。我可能会检测QueryFullProcessImageName
是否可用并尽可能使用它,否则会回到GetModuleFileNameEx
。
编辑:虽然GetModuleFileNameEx
并非100%可靠地检索每个可能进程的可执行文件的名称,但它至少在相当长的一部分时间内起作用。以下是我编写的一小段测试代码:
#include <windows.h>
#include <psapi.h>
#include <iterator>
#include <iostream>
#include <string>
#include <map>
std::string getfilename(DWORD pid) {
HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid);
static int winver;
char path[256]= {0};
DWORD size = sizeof(path);
if (winver==0)
winver = GetVersion() & 0xf;
#if WINVER >= 0x600
if (winver >= 6)
QueryFullProcessImageName(process, 0, path, &size);
else
#endif
if (!GetModuleFileNameEx(process, NULL, path, sizeof(path)))
strcpy(path, "Unknown");
return std::string(path);
}
typedef std::map<DWORD, std::string> win_map;
namespace std {
ostream &operator<<(ostream &os, win_map::value_type const &v) {
return os << v.first << ": " << v.second;
}
}
BOOL CALLBACK show_info(HWND window, LPARAM lParam) {
win_map &exes = *(win_map *)lParam;
DWORD pid;
GetWindowThreadProcessId(window, &pid);
exes[pid] = getfilename(pid);
return true;
}
int main() {
win_map exes;
EnumWindows(show_info, (LPARAM)&exes);
std::copy(exes.begin(), exes.end(), std::ostream_iterator<win_map::value_type>(std::cout, "\n"));
return 0;
}
快速测试的结果有点有趣。编译为32位代码,使用QueryFullProcessImageName
的版本找到了33个具有顶级窗口的进程,并找到了其中31个可执行文件的名称。使用GetModuleFileNameEx
的版本也找到了33个进程,但只找到了21个可执行文件的名称。但是,如果我将其编译为64位代码,那么 版本会找到33个可执行文件中的31个的文件名(并且相同的两个失败)。考虑到你看XP / x64的频率,这可能没那么重要,但我发现它很有趣。
在任何情况下,即使功能最弱的版本(32位/ GMFNE)也会找到文件的~2 / 3 rds 的名称。虽然那肯定不是你所希望的,但肯定比什么都好。
答案 1 :(得分:1)
必须可以检索正在运行的进程的文件路径,因为Sysinternals的Process Explorer可以执行此操作。当然,Process Explorer使用NtQueryInformationProcess,这不是受支持的功能。 (另一方面,由于您专门针对XP并且将在Vista及更高版本上使用QueryFullProcessImageName
,因此担心API在未来版本的Windows中不可用可能不是一个问题。)
CodeProject has an article about how to use NtQueryInformationProcess