我正在尝试获取在C# 2.0应用程序之外的窗口可执行文件的名称。我的应用程序当前使用来自"user32.dll"的GetForegroundWindow()调用获取窗口句柄(hWnd)。
通过我的研究,我认为我想要使用GetModuleFileNameEx()函数(来自PSAPI)来获取名称,但是GetModuleFileNameEx()需要一个进程句柄,而不是窗口句柄。
是否有可能从窗口句柄获取进程句柄?(我需要首先获取窗口的线程句柄吗?)
编辑了第一句话以使我正在尝试做什么更清晰。
更新! 这是我找到适用于我的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());
}