none
Get URLs of pages opened in MS-Edge Browser is not working in Windows 10 Home Edition(Upgraded from Windows 8.1) using C# RRS feed

  • Question

  • Hi All,

    I have tired with below code to get the URL and Title of all the pages opened in MS-Edge browser.

    IUIAutomationElement rootElement = uiAutomation.GetRootElement();
    
    int propertyName = 30005; // UIA_NamePropertyId
    int propertyAutomationId = 30011; // UIA_AutomationIdPropertyId
    int propertyClassName = 30012; // UIA_ClassNamePropertyId
    int propertyNativeWindowHandle = 30020; // UIA_NativeWindowHandlePropertyId
    
    // Get the main Edge element, which is a direct child of the UIA root element.
    // For this test, assume that the Edge element is the only element with an
    // AutomationId of "TitleBar".
    string edgeAutomationId = "TitleBar";
    
    IUIAutomationCondition condition = 
        uiAutomation.CreatePropertyCondition(
            propertyAutomationId, edgeAutomationId);
    
    // Have the window handle cached when we find the main Edge element.
    IUIAutomationCacheRequest cacheRequestNativeWindowHandle = uiAutomation.CreateCacheRequest();
    cacheRequestNativeWindowHandle.AddProperty(propertyNativeWindowHandle);
    
    IUIAutomationElement edgeElement = 
        rootElement.FindFirstBuildCache(
            TreeScope.TreeScope_Children, 
            condition,
            cacheRequestNativeWindowHandle);
    
    if (edgeElement != null)
    {
        IntPtr edgeWindowHandle = edgeElement.CachedNativeWindowHandle;
    
        // Next find the element whose name is the url of the loaded page. And have
        // the name of the element related to the url cached when we find the element.
        IUIAutomationCacheRequest cacheRequest =
            uiAutomation.CreateCacheRequest();
        cacheRequest.AddProperty(propertyName);
    
        // For this test, assume that the element with the url is the first descendant element
        // with a ClassName of "Internet Explorer_Server".
        string urlElementClassName = "Internet Explorer_Server";
    
        IUIAutomationCondition conditionUrl =
            uiAutomation.CreatePropertyCondition(
                propertyClassName,
                urlElementClassName);
    
        IUIAutomationElement urlElement =
            edgeElement.FindFirstBuildCache(
                TreeScope.TreeScope_Descendants,
                conditionUrl,
                cacheRequest);
    
        string url = urlElement.CachedName;
    
        // Next find the title of the loaded page. First find the list of 
        // tabs shown at the top of Edge.
        string tabsListAutomationId = "TabsList";
    
        IUIAutomationCondition conditionTabsList =
            uiAutomation.CreatePropertyCondition(
                propertyAutomationId, tabsListAutomationId);
    
        IUIAutomationElement tabsListElement =
            edgeElement.FindFirst(
                TreeScope.TreeScope_Descendants,
                conditionTabsList);
    
        // Find which of those tabs is selected. (It should be possible to 
        // cache the Selection pattern with the above call, and that would
        // avoid one cross-process call here.)
        int selectionPatternId = 10001; // UIA_SelectionPatternId
        IUIAutomationSelectionPattern selectionPattern = 
            tabsListElement.GetCurrentPattern(selectionPatternId);
    
        // For this test, assume there's always one selected item in the list.
        IUIAutomationElementArray elementArray = selectionPattern.GetCurrentSelection();
        string title = elementArray.GetElement(0).CurrentName;
    
        // Now show the title, url and window handle.
        MessageBox.Show(
            "Page title: " + title +
            "\r\nURL: " + url + 
            "\r\nhwnd: " + edgeWindowHandle);
    }

    Ref: Guy Barker's code from link Microsoft Edge: Get Window URL and Title

    Note: This code using the unmanaged Windows 7 UI Automation API. The sample has a custom build step: "%PROGRAMFILES%\Microsoft SDKs\Windows\v7.0A\bin\tlbimp.exe" %windir%\system32\UIAutomationCore.dll /out:..\interop.UIAutomationCore.dll"

    This code is working great in Windows 10 Professional machine.

    If I have tried the same code in Windows 10 Home Edition(upgraded from windows 8.1) machine, its not working and the"urlElement" return null for me. The code not find the "Internet Explorer_Server" class. But the "Internet Explorer_Server" class has found while navigate using inspect.exe.

    string urlElementClassName = "Internet Explorer_Server";

    IUIAutomationCondition conditionUrl = uiAutomation.CreatePropertyCondition(propertyClassName,urlElementClassName);

    IUIAutomationElement urlElement = edgeElement.FindFirstBuildCache( TreeScope.TreeScope_Descendants, conditionUrl, cacheRequest);

    if(urlElement == null)//true

    I have explore further, the code not capture pane(Spartan XAML-To-Trident Input Routing Window) node in windows 10 Home edition machine. So i could not reach "Internet Explorer_Server" class to find URL.

    Is any difference between home and professional edition OS? How to solve it?

    Thanks

    Satheesh


    Thursday, September 3, 2015 5:42 AM

All replies

  • Missing classes in Win10 Home Edition
    Friday, September 4, 2015 6:19 AM
  • The "Internet Explorer_Server" class has exist in Win10 Home Edition. The "Internet Explorer_Server" class has found while I navigate using inspect.exe(UI tool). But if i tired to access "Internet Explorer_Server"class though code it showing as null. I could not access this class from code.

    This code working in windows 10 Professional Edition, but not in windows10 Home Edition(upgraded from windows 8).

    How can i access the "Internet Explorer_Server" class in windows10 Home Edition(upgraded from windows 8) through c# code?

    Thanks

    Satheesh


    Tuesday, September 8, 2015 3:28 AM
  • Hi Satheesh,

    i tried get the url and title from Microsoft Edge without UI Automation.
    (ref. https://support.microsoft.com/en-us/kb/249232 )
    it can work under my environment(Win 10 x86 Home).

    using System;
    using System.Text;
    using System.Runtime.InteropServices;
    
    namespace Sample
    {
      class Program
      {
        [Flags]
        private enum SendMessageTimeoutFlags : uint
        {
          SMTO_NORMAL = 0x0000,
          SMTO_BLOCK = 0x0001,
          SMTO_ABORTIFHUNG = 0x0002,
          SMTO_NOTIMEOUTIFNOTHUNG = 0x0008,
          SMTO_ERRORONEXIT = 0x0020
        }
        private delegate bool Win32Callback(IntPtr hWnd, ref IntPtr lParam);
        
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool EnumWindows(Win32Callback lpEnumFunc, ref IntPtr lParam);
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool EnumChildWindows(IntPtr hWndParent, Win32Callback lpEnumFunc, IntPtr lParam);
        [DllImport("user32.dll", SetLastError = true)]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
        [DllImport("oleacc.dll", PreserveSig=false)]
        [return: MarshalAs(UnmanagedType.Interface)]
        private static extern object ObjectFromLresult(UIntPtr lResult, [MarshalAs(UnmanagedType.LPStruct)] Guid refiid, IntPtr wParam);
        [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
        private static extern uint RegisterWindowMessage(string lpString);
        [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
        private static extern IntPtr SendMessageTimeout(IntPtr windowHandle, uint Msg, IntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags flags, uint timeout, out UIntPtr result);
        
        public static void Main(string[] args)
        {
          IntPtr hEdge = IntPtr.Zero;
          Win32Callback proc = new Win32Callback(EnumWindowsProc);
          EnumWindows(proc, ref hEdge);
          if (hEdge != IntPtr.Zero) {
            Win32Callback childProc = new Win32Callback(EnumChildProc);
            EnumChildWindows(hEdge, childProc, IntPtr.Zero);
          }
          Console.Write("Press any key to continue . . . ");
          Console.ReadKey(true);
        }
        
        //get a Edge window('Windows.UI.Core.CoreWindow' Class)
        private static bool EnumWindowsProc(IntPtr hWnd, ref IntPtr lParam)
        {
          IntPtr hChild = IntPtr.Zero;
          StringBuilder buf = new StringBuilder(1024);
          StringBuilder buf2 = new StringBuilder(1024);
          GetClassName(hWnd, buf, buf.Capacity);
          switch (buf.ToString()) {
            case "ApplicationFrameWindow": //normal window
              hChild = FindWindowEx(hWnd, IntPtr.Zero, "Windows.UI.Core.CoreWindow", "Microsoft Edge");
              if (hChild != IntPtr.Zero) {
                lParam = hChild;
                return false;
              }
              break;
            case "Windows.UI.Core.CoreWindow": //minimized window 
              hChild = FindWindowEx(hWnd, IntPtr.Zero, "Spartan XAML-To-Trident Input Routing Window", "");
              GetWindowText(hWnd, buf2, buf2.Capacity);
              if (hChild != IntPtr.Zero && buf2.ToString() == "Microsoft Edge") {
                lParam = hWnd;
                return false;
              }
              break;
          }
          return true;
        }
        
        //get 'Internet Explorer_Server' window
        private static bool EnumChildProc(IntPtr hWnd, ref IntPtr lParam)
        {
          dynamic doc = null;
          StringBuilder buf = new StringBuilder(1024);
          GetClassName(hWnd, buf, buf.Capacity);
          if (buf.ToString() == "Internet Explorer_Server") {
            doc = GetHTMLDocumentFromWindow(hWnd);
            if (doc != null) {
              Console.WriteLine(doc.Title + ", " + doc.url); //get document title & url
            }
          }
          return true;
        }
        
        //get HTMLDocument object
        private static object GetHTMLDocumentFromWindow(IntPtr hWnd)
        {
          UIntPtr lRes;
          object doc = null;
          Guid IID_IHTMLDocument = new Guid("626FC520-A41E-11CF-A731-00A0C9082637");
          uint nMsg = RegisterWindowMessage("WM_HTML_GETOBJECT");
          if (nMsg != 0) {
            SendMessageTimeout(hWnd, nMsg, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 1000, out lRes);
            if (lRes != UIntPtr.Zero) {
              doc = ObjectFromLresult(lRes, IID_IHTMLDocument, IntPtr.Zero);
            }
          }
          return doc;
        }
      }
    }



    Regards,
    kinuasa
    Tuesday, October 6, 2015 4:47 AM
  • This method works only when EDGE window is maximized. Can you please suggest how to get url if EDGE is minimized ?

    armujahid

    Sunday, June 11, 2017 8:36 AM
  • Hi kinuasa,

    Hope you are doing fine. I need to ask you about your above code. How can I get the active tab(s) only? Your code returns everything that is being opened.

    Tuesday, June 13, 2017 5:02 AM
  • Hi Guys,

    The above code is not working in latest Microsoft Edge browser v40+. It failed to capture the active tab title of maximized edge browser. How can i get the tab titles in both latest and older versions of edge browser?

    Also please let me how to capture all tab titles and its urls from edge browser.

    Thanks,

    Satheesh

    Tuesday, June 19, 2018 1:58 PM