locked
Process.MainWindowHandle returns 0 for too many processes (with UI)! RRS feed

  • Question

  • Hello,

    I'm trying to get a window handle on few running applications, like calculator and notepad. So I can maximize or minimize them as I need to.

    It works well for "notepad" but it fails for "calculator" and many other processes (even if they have ui windows).

    Here is a simplify sample code

                        Process[] anotherApps = Process.GetProcessesByName("Calculator");
                        if (anotherApps>lenght>0 && anotherApps[0].MainWindowHandle.ToInt32() != 0)
                        {
                            Console.Out.WriteLine(anotherApps [0].Id + " - " + anotherApps [0].MainWindowTitle + " - " + anotherApps [0].ProcessName);

                               }

    I tried different option I read on the internet (sleep for few ms) etc... but none seems to get me the right handle for Calculator for instance.

    Thanks for your help


    w.


    • Edited by wil70 Thursday, May 25, 2017 5:51 AM
    Thursday, May 25, 2017 5:50 AM

Answers

  • Hi wil70,

    Thank you for posting here.

    For your question, please try the following code. 

      static void Main(string[] args)
            {
                Process[] anotherApps = Process.GetProcessesByName("Calculator");
    
                while (anotherApps[0].MainWindowHandle.ToInt32() == 0)
                {
                    anotherApps[0].Refresh();
                }
                if (anotherApps[0].MainWindowHandle.ToInt32() != 0)
                {
                    Console.Out.WriteLine("successTest" + anotherApps[0].MainWindowHandle.ToInt32());
                    Console.ReadKey();
                }
    
            }

    When I open a caculator and run the project, it will get the MainWindowHandle.

    Or you could try another way.

      [DllImport("user32.dll", EntryPoint = "FindWindow")]
            private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
    
            static void Main(string[] args)
            {
                IntPtr hwnd = FindWindow(null, "Calculator");
                Console.WriteLine(hwnd.ToString());
                Console.ReadKey();
            }

    I use another computer to test, it works well. Please have a try.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Friday, May 26, 2017 9:17 AM

All replies

  • Have you tried “Calc” instead of “Calculator”?

    Thursday, May 25, 2017 6:08 AM
  • For "Calc" it doesn't work, it can not find the process.

    For "Calculator", it does find the process but for "calculator" (like 70% of the processes with UI) it does return 0 as the MainWindowHandle instead of a handle > 0

    How do I fix this? 

    Are you able to make it work on you machine?

    It seems like a bug correct? when can this be fix?

    thanks

    • Edited by wil70 Friday, May 26, 2017 2:47 AM
    Thursday, May 25, 2017 5:31 PM
  • Hi wil70,

    Thank you for posting here.

    For your question, please try the following code. 

      static void Main(string[] args)
            {
                Process[] anotherApps = Process.GetProcessesByName("Calculator");
    
                while (anotherApps[0].MainWindowHandle.ToInt32() == 0)
                {
                    anotherApps[0].Refresh();
                }
                if (anotherApps[0].MainWindowHandle.ToInt32() != 0)
                {
                    Console.Out.WriteLine("successTest" + anotherApps[0].MainWindowHandle.ToInt32());
                    Console.ReadKey();
                }
    
            }

    When I open a caculator and run the project, it will get the MainWindowHandle.

    Or you could try another way.

      [DllImport("user32.dll", EntryPoint = "FindWindow")]
            private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
    
            static void Main(string[] args)
            {
                IntPtr hwnd = FindWindow(null, "Calculator");
                Console.WriteLine(hwnd.ToString());
                Console.ReadKey();
            }

    I use another computer to test, it works well. Please have a try.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Friday, May 26, 2017 9:17 AM
  • Super - thanks a lot Wendy

    So for windows 10 pro (latest update), the first method with the Refresh() doesn't work, it goes into a infinite loop.

    But the second method with the FindWindow works well (I did try in the past but like this FindWindow(String.Empty, "Calculator") ;) and that didn't work....

    Thanks again, 

    Best

    Wilhelm

    Note: I do not know if a bug need to be reported for win 10 Pro with the first method...


    w.

    Saturday, May 27, 2017 7:34 PM
  • So for windows 10 pro (latest update), the first method with the Refresh() doesn't work, it goes into a infinite loop. 

    Hi,

    by my experience, it is happening only if the process of searching is showing on the screen, so hiding the process' window is partially resolving this issue

    Wednesday, August 1, 2018 3:26 PM