如何在C#/Win32中获取正在运行的进程的DOS路径名?
总而言之,我需要这样做: 12345(hWnd)->“C:\setup.exe”如何在C#/Win32中获取正在运行的进程的DOS路径名?,c#,.net,winapi,interop,C#,.net,Winapi,Interop,总而言之,我需要这样做: 12345(hWnd)->“C:\setup.exe” 现在,我正在使用来检索进程句柄的内核设备路径。我正在使用检索句柄,并将PID传递给它。正在使用检索PID(我也需要它) 然而,这让我想到了一个字符串,比如: \设备\Harddisk1\setup.exe 此时,我使用枚举系统上的所有驱动器,然后调用。最后,我可以做一些字符串操作魔术,并且“砰”我有我的路径。 好的,那么我的问题是: 此过程在网络驱动器上发生故障。 我真正想要的是XP 必须有更好的方法来做到这一
现在,我正在使用来检索进程句柄的内核设备路径。我正在使用检索句柄,并将PID传递给它。正在使用检索PID(我也需要它) 然而,这让我想到了一个字符串,比如: \设备\Harddisk1\setup.exe 此时,我使用枚举系统上的所有驱动器,然后调用。最后,我可以做一些字符串操作魔术,并且“砰”我有我的路径。
好的,那么我的问题是:
必须有更好的方法来做到这一点。请启发我,哦,WIN32API的神 一个显而易见的问题是,如果您想要的话,为什么不直接使用
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;
}
#包括
#包括
#包括
#包括
#包括
#包括
std::string getfilename(DWORD pid){
HANDLE process=OpenProcess(process_QUERY_INFORMATION | process_VM_READ,false,pid);
静态int-winver;
字符路径[256]={0};
DWORD大小=sizeof(路径);
如果(winver==0)
winver=GetVersion()&0xf;
#如果WINVER>=0x600
如果(winver>=6)
QueryFullProcessImageName(进程、0、路径和大小);
其他的
#恩迪夫
if(!GetModuleFileNameEx(进程,NULL,路径,sizeof(路径)))
strcpy(路径,“未知”);
返回std::字符串(路径);
}
typedef std::map win_map;
命名空间std{
ostream&operator一个显而易见的问题是,如果您想要的话,为什么不直接使用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;
}
#包括
#包括
#包括
#包括
#包括
#包括
std::string getfilename(DWORD pid){
HANDLE process=OpenProcess(process_QUERY_INFORMATION | process_VM_READ,false,pid);
静态int-winver;
字符路径[256]={0};
DWORD大小=sizeof(路径);
如果(winver==0)
winver=GetVersion()&0xf;
#如果WINVER>=0x600
如果(winver>=6)
QueryFullProcessImageName(进程、0、路径和大小);
其他的
#恩迪夫
if(!GetModuleFileNameEx(进程,NULL,路径,sizeof(路径)))
strcpy(路径,“未知”);
返回std::字符串(路径);
}
typedef std::map win_map;
命名空间std{
ostream&operator必须能够检索运行进程的文件路径,因为Sysinternals的Process Explorer可以检索文件路径。当然,Process Explorer使用,这是不受支持的函数。(另一方面,由于您专门针对XP,并且会在Vista和更高版本上使用QueryFullProcessImageName
,因此担心API在未来版本的Windows中不可用可能不是一个问题。)
.必须能够检索到运行进程的文件路径,因为Sysinternals的Process Explorer可以检索到该路径。当然,Process Explorer使用,这是不受支持的功能。(另一方面,由于您专门针对XP,并且会在Vista和更高版本上使用QueryFullProcessImageName
,因此担心API在未来版本的Windows中不可用可能不是一个问题。)
.您/您的进程具有枚举管理权限吗?但是,我只是检索驱动器名。您/您的进程具有枚举管理权限吗?但是,我只是检索驱动器名。QueryFullProcessImageName在XP上不起作用。是的,我需要它在旧操作系统上工作。我计划使用Vista+api(如果受支持的话)。哦,而且GetModuleFileNameEx
不适用于另一个进程中的模块。同样适用!现在是当前的GetVersion()不推荐使用。也许我们应该寻找一个替代函数。@Jean PhilippeMond:QueryFullProcessImageName在XP上不起作用。是的,我需要它在旧的操作系统上工作。如果支持,我计划使用Vista+api。哦,GetModuleFileNameEx
不适用于另一个进程中的模块。同样有效!现在当前GetVersion()已弃用。也许我们应该寻找一个替代函数。@Jean PhilippeMond: