none
Get exe name from a window handle RRS feed

  • Question

  • Hi,

    I have the current foreground window handle and I want to use it to grab the name of the exe that owns the process using the handle.  I have tried a few pInvokes but I cannot work it out.

    I tried using the following method:

            [DllImport("coredll.dll", SetLastError = true)]
            private static extern int GetModuleFileName(IntPtr hModule, StringBuilder lpFilename, int nSize);

    So, tried to call GetModuleFileName using the handle of the foreground window but I think it must be different from the hModule handle as I find the string builder object is not populated when I run the method.

    Has anyone experience with this where they can point me right direction.  What I want to end up with is the name of the exe of the current foreground window.  I don't really want to parse a list of process entries to get this sort of information.

    Thanks!







    Rob McCabe
    Tuesday, December 15, 2009 5:18 PM

Answers

  • Hi Rob,

    In my previous post getting the window handle is just a sample, in fact, we can use  GetForegroundWindow to foreground window. Here is the c# completed code:

    [DllImport("coredll.dll", SetLastError = true)]

            static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

     

            [DllImport("coredll.dll")]

            static extern IntPtr GetForegroundWindow();

     

            [DllImport("coredll.dll", SetLastError = true)]

            private static extern int GetModuleFileName(IntPtr hModule, StringBuilder lpFilename, int nSize); 

     

     

            private void Form1_Load(object sender, EventArgs e)

            {

                uint processID = 0;

                uint threadID = GetWindowThreadProcessId(GetForegroundWindow(), out processID);

     

                StringBuilder exePath = new StringBuilder(1024);

                int exePathLen = GetModuleFileName((IntPtr)processID, exePath, exePath.Capacity);

            }

    It works fine in my local.


    Best regards,
    Guang-Ming Bian - MSFT


    Please remember to mark the replies as answers if they help and unmark them if they provide no help
    Wednesday, December 23, 2009 3:56 AM
    Moderator

All replies

  • Hi Rob,

     

    We can use GetWindowThreadProcessId to get process ID from window handle. In fact,the process ID is module handle, we just convert it to HMODULE, then call GetModuleFileName to get full process name, like the code below:

     

          HWND   h;

          WCHAR processName[255];

          DWORD PID;

     

          BOOL find = FALSE;

     

          //get exact window handle

          h = FindWindow(NULL,L"Form11")->m_hWnd;

          GetWindowThreadProcessId(h, &PID);

          GetModuleFileName((HMODULE)PID,processName,100);


    processName variable will get the process name.
     

    Best regards,

    Guang-Ming Bian - MSFT


    Please remember to mark the replies as answers if they help and unmark them if they provide no help
    Monday, December 21, 2009 4:21 AM
    Moderator
  • Hi Guang-Ming,

    Thanks for the reply.  I cannot get this C# code to compile.  Also, I noticed you have specified the name "Form1" in the find window, what if the name of the topmost form is not known?

    Can something like this be used to get the exact text of the foreground window as well?

    Regards,

    Robert

    Rob McCabe
    Tuesday, December 22, 2009 10:57 AM
  • Hi Rob,

    In my previous post getting the window handle is just a sample, in fact, we can use  GetForegroundWindow to foreground window. Here is the c# completed code:

    [DllImport("coredll.dll", SetLastError = true)]

            static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

     

            [DllImport("coredll.dll")]

            static extern IntPtr GetForegroundWindow();

     

            [DllImport("coredll.dll", SetLastError = true)]

            private static extern int GetModuleFileName(IntPtr hModule, StringBuilder lpFilename, int nSize); 

     

     

            private void Form1_Load(object sender, EventArgs e)

            {

                uint processID = 0;

                uint threadID = GetWindowThreadProcessId(GetForegroundWindow(), out processID);

     

                StringBuilder exePath = new StringBuilder(1024);

                int exePathLen = GetModuleFileName((IntPtr)processID, exePath, exePath.Capacity);

            }

    It works fine in my local.


    Best regards,
    Guang-Ming Bian - MSFT


    Please remember to mark the replies as answers if they help and unmark them if they provide no help
    Wednesday, December 23, 2009 3:56 AM
    Moderator
  • Hi Guang,

    Thanks for that c# code.  Unfortunately this is producing an overflow exception for me.  Seems to be when carrying out the boxing of the processID to IntPtr.

    A first chance exception of type 'System.OverflowException' occurred in mscorlib.dll
    '(IntPtr)processID' threw an exception of type 'System.OverflowException'
        base {System.ArithmeticException}: {"OverflowException"}

    Any ideas?  I get this when trying the exact code above.



    Rob McCabe
    Wednesday, December 23, 2009 10:31 AM
  • It's an uint, so converting it to an IntPtr will sometimes fail if the returned value truly is uint.
    You can try change the pinvoke signature of GetModuleFileName to

            [DllImport("coredll.dll", SetLastError = true)]
            private static extern int GetModuleFileName(UIntPtr hModule, StringBuilder lpFilename, int nSize);

    and the boxing to UIntPtr:

                StringBuilder exePath = new StringBuilder(1024);
                int exePathLen = GetModuleFileName((UIntPtr)processID, exePath, exePath.Capacity);


    Ray
    Thursday, December 24, 2009 12:48 AM
  • Hi Ray,

    Thanks that works great now thanks!  i didnt realise you could modify the signature of pInvoke code.  



    Rob McCabe
    Thursday, December 24, 2009 10:42 AM