当前位置:  开发笔记 > 编程语言 > 正文

如果我只有一个窗口句柄(hWnd),我如何GetModuleFileName()?

如何解决《如果我只有一个窗口句柄(hWnd),我如何GetModuleFileName()?》经验,为你挑选了2个好方法。

我正在尝试获取我的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());
}

小智.. 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;
}

我认为到目前为止,这是这里提供的最佳解决方案.没有奇怪的字符,最重要的是,不依赖于不一致的GetModuleFileNameEx函数,它在Windows 7上位于另一个DLL(不是psapi而是kernel32)中.在这种情况下,使用.Net类绝对是首选.完美的工作. (2认同)

我意识到这个线程已经过时,但对这个建议的解决方案有一点点评论.如果您尝试从32位进程获取64位进程的文件名(反之亦然),则无效. (2认同)


小智.. 6

您可以调用GetWindowThreadProcessId,它将返回与窗口关联的进程.

从那里,您可以调用OpenProcess来打开进程并获取进程的句柄.



1> 小智..:

一直在努力解决同样的问题一小时了,还得到了第一个字母换成的通过使用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;
}


我认为到目前为止,这是这里提供的最佳解决方案.没有奇怪的字符,最重要的是,不依赖于不一致的GetModuleFileNameEx函数,它在Windows 7上位于另一个DLL(不是psapi而是kernel32)中.在这种情况下,使用.Net类绝对是首选.完美的工作.
我意识到这个线程已经过时,但对这个建议的解决方案有一点点评论.如果您尝试从32位进程获取64位进程的文件名(反之亦然),则无效.

2> 小智..:

您可以调用GetWindowThreadProcessId,它将返回与窗口关联的进程.

从那里,您可以调用OpenProcess来打开进程并获取进程的句柄.

推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有