Search code examples
c#winapihwndgetmodulefilename

How do I GetModuleFileName() if I only have a window handle (hWnd)?


I'm trying to get the name of the executable of a window that is outside my C# 2.0 application. My app currently gets a window handle (hWnd) using the GetForegroundWindow() call from "user32.dll".

From the digging that I've been able to do, I think I want to use the GetModuleFileNameEx() function (from PSAPI) to obtain the name, but GetModuleFileNameEx() requires a handle to a Process, not a Window.

Is it possible to get a process handle from a window handle? (Do I need to get the thread handle of the window first?)

EDITED the first sentence to make it clearer what I'm trying to do.

UPDATE! Here's the C# code that I found worked for me. The only caveat is occasionally it returns a file/path where the drive letter is a "?" instead of the actual drive letter (like "C"). -- Haven't figured out why yet.

[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());
}

Solution

  • You can call GetWindowThreadProcessId and that will return you the process associated with the window.

    From that, you can call OpenProcess to open the process and get the handle to the process.