Search code examples
c#.netwindowshandle

How to access a window?


I'm trying to access a specific window using its handle (that is System.IntPtr value):

        // Getting the process of Visual Studio program
        var process = Process.GetProcessesByName("devenv")[0];

        // Showing the handle we've got, we've no problem
        MessageBox.Show(this, process.MainWindowHandle.ToString());

        // Attempting to get the main window object by its handle
        var wnd = NativeWindow.FromHandle(process.MainWindowHandle);

        // always fails
        if (wnd == null)
            MessageBox.Show("Failed");
        else
            MessageBox.Show(wnd.ToString(), "Yeeeeees!!");

I have tried also to access another demo .net winforms application's main window, that I have made for this purpose, (i.e. I run the demo application, and attempted to access its main window by this application), and failed, too, although both the demo and this application are .NET applications. However, this successes:

        var process2 = Process.GetCurrentProcess();
        MessageBox.Show(this, process2.MainWindowHandle.ToString());

        var wnd2 = NativeWindow.FromHandle(process2.MainWindowHandle);
        if (wnd2 == null)
            MessageBox.Show("Failed");
        else
            MessageBox.Show(wnd2.ToString(), "Yes");

I think this works because it is invoked from the same application. So, how can I access some another program's window object by its handle? I thought it can work using C\C++ by using header file <windows.h> and then using a P\invoke.

If I can't, is there another way to access a window (i.e. rather than using handles)?

=================== EDIT

I want to deal with the entire window object and its own controls


Solution

  • Then, as Raymond suggested, why don't you try with Automation? Add a console project with references to UIAutomationClient and UIAutomationTypes

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Automation;
    using System.Diagnostics;
    using System.Threading;
    
    namespace ConsoleApplication
    {
        class Program
        {
            static void Main(string[] args)
            {
                var pInfo = new ProcessStartInfo("notepad");
    
                var p = Process.Start(pInfo);
    
                p.WaitForInputIdle();
    
                AutomationElement installerEditorForm = AutomationElement.FromHandle(p.MainWindowHandle);
    
                // menus
                AutomationElementCollection menuBars = installerEditorForm.FindAll(TreeScope.Children, new PropertyCondition(
                    AutomationElement.ControlTypeProperty, ControlType.MenuBar));
    
                var mainMenuItem = menuBars[0];
    
                AutomationElementCollection menus = mainMenuItem.FindAll(TreeScope.Children, new PropertyCondition(
                    AutomationElement.ControlTypeProperty, ControlType.MenuItem));
    
                var fileMenuItem = menus[0];
    
                ExpandCollapsePattern fileMenuItemOpenPattern = (ExpandCollapsePattern)fileMenuItem.GetCurrentPattern(
                    ExpandCollapsePattern.Pattern);
    
                fileMenuItemOpenPattern.Expand();
    
                AutomationElement fileMenuItemNew = fileMenuItem.FindFirst(TreeScope.Children,
                    new AndCondition(
                        new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.MenuItem),
                        new PropertyCondition(AutomationElement.NameProperty, "New")));
    
                Console.Read();
            }
        }
    }
    

    reference