我正在尝试获取我的C#2.0应用程序之外的窗口的可执行文件的名称.我的应用程序当前使用来自"user32.dll"的GetForegroundWindow()调用获取窗口句柄(hWnd).
从我能够做的挖掘,我想我想使用GetModuleFileNameEx()函数(来自PSAPI)来获取名称,但GetModuleFileNameEx()需要一个Process的句柄,而不是一个Window.
是否可以从窗口句柄获取进程句柄?(我是否需要先获取窗口的线程句柄?)
编辑了第一句话,使我更清楚我正在尝试做什么.
UPDATE!这是我发现为我工作的C#代码.唯一需要注意的是偶尔它返回一个文件/路径,其中驱动器盘符是"?" 而不是实际的驱动器号(如"C"). - 还没弄明白为什么呢.
[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("kernel32.dll")]
static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
[DllImport("psapi.dll")]
static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName, [In] [MarshalAs(UnmanagedType.U4)] int nSize);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);
private string GetWindowModuleFileName(IntPtr hWnd)
{
uint processId = 0;
const int nChars = 1024;
StringBuilder filename = new StringBuilder(nChars);
GetWindowThreadProcessId(hWnd, out processId);
IntPtr hProcess = OpenProcess(1040, 0, processId);
GetModuleFileNameEx(hProcess,IntPtr.Zero,filename,nChars);
CloseHandle(hProcess);
return (filename.ToString());
}
Run Code Online (Sandbox Code Playgroud)
小智 8
一直在努力解决同样的问题一小时了,还得到了第一个字母换成的?通过使用GetModuleFileNameEx.最后使用System.Diagnostics.Process类提出了这个解决方案.
[DllImport("user32.dll")]
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
void GetProcessPathFromWindowHandle(IntPtr hwnd)
{
uint pid = 0;
Win32.GetWindowThreadProcessId(hwnd, out pid);
Process p = Process.GetProcessById((int)pid);
return p.MainModule.FileName;
}
Run Code Online (Sandbox Code Playgroud)