【问题标题】:c# Getting Chrome URL's from all tabc#从所有选项卡获取Chrome URL
【发布时间】:2016-07-30 16:48:54
【问题描述】:

嗨,我想从浏览器获取 URL,对于 chrome,我使用了这些,但无法正常工作,出现 null 异常,我认为 chrome 已经改变了一些东西.. 在 elm4 == null 上出现错误。

我使用 UIAutomation 进行了更多搜索,但所有示例均无效...

参考:- https://stackoverflow.com/a/21799588/5096993 https://social.msdn.microsoft.com/Forums/vstudio/en-US/39bf60a8-2bdc-4aa0-96fb-08dca49cdb06/c-get-all-chrome-urls-opened?forum=csharpgeneral

else if (browser == BrowserType.Chrome)
            {
                //"Chrome_WidgetWin_1"

                Process[] procsChrome = Process.GetProcessesByName("chrome");
                foreach (Process chrome in procsChrome)
                {
                    // the chrome process must have a window
                    if (chrome.MainWindowHandle == IntPtr.Zero)
                    {
                        continue;
                    }
                    //AutomationElement elm = AutomationElement.RootElement.FindFirst(TreeScope.Children,
                    //         new PropertyCondition(AutomationElement.ClassNameProperty, "Chrome_WidgetWin_1"));
                    // find the automation element
                    AutomationElement elm = AutomationElement.FromHandle(chrome.MainWindowHandle);

                    // manually walk through the tree, searching using TreeScope.Descendants is too slow (even if it's more reliable)
                    AutomationElement elmUrlBar = null;
                    try
                    {
                        // walking path found using inspect.exe (Windows SDK) for Chrome 29.0.1547.76 m (currently the latest stable)
                        var elm1 = elm.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Google Chrome"));
                        var elm2 = TreeWalker.ControlViewWalker.GetLastChild(elm1); // I don't know a Condition for this for finding :(
                        var elm3 = elm2.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, ""));
                        var elm4 = elm3.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ToolBar));
                        elmUrlBar = elm4.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Address and search bar"));
                    }
                    catch
                    {
                        // Chrome has probably changed something, and above walking needs to be modified. :(
                        // put an assertion here or something to make sure you don't miss it
                        continue;
                    }

                    // make sure it's valid
                    if (elmUrlBar == null)
                    {
                        // it's not..
                        continue;
                    }

                    // elmUrlBar is now the URL bar element. we have to make sure that it's out of keyboard focus if we want to get a valid URL
                    if ((bool)elmUrlBar.GetCurrentPropertyValue(AutomationElement.HasKeyboardFocusProperty))
                    {
                        continue;
                    }

                    // there might not be a valid pattern to use, so we have to make sure we have one
                    AutomationPattern[] patterns = elmUrlBar.GetSupportedPatterns();
                    if (patterns.Length == 1)
                    {
                        string ret = "";
                        try
                        {
                            ret = ((ValuePattern)elmUrlBar.GetCurrentPattern(patterns[0])).Current.Value;
                        }
                        catch { }
                        if (ret != "")
                        {
                            // must match a domain name (and possibly "https://" in front)
                            if (Regex.IsMatch(ret, @"^(https:\/\/)?[a-zA-Z0-9\-\.]+(\.[a-zA-Z]{2,4}).*$"))
                            {
                                // prepend http:// to the url, because Chrome hides it if it's not SSL
                                if (!ret.StartsWith("http"))
                                {
                                    ret = "http://" + ret;
                                }
                                return ret;
                            }
                        }
                        continue;
                    }
                }

            }

【问题讨论】:

    标签: c# google-chrome monitoring ui-automation


    【解决方案1】:

    代码如下:

    AutomationElement root = AutomationElement.FromHandle(proc.MainWindowHandle);
    Condition condNewTab = new PropertyCondition(AutomationElement.NameProperty, "Novo separador");
    AutomationElement elmNewTab = root.FindFirst(TreeScope.Descendants, condNewTab);
    TreeWalker treewalker = TreeWalker.ControlViewWalker;
    
    // IF THROWS A ERROR HERE, LOOK AT THE AutomationElement.NameProperty ("Novo separador") - PUT THIS TEXT IN APROPRIATE LANGUAGE
    AutomationElement elmTabStrip = treewalker.GetParent(elmNewTab);
                                                                                
    Condition condTabItem = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TabItem);
    foreach (AutomationElement tabitem in elmTabStrip.FindAll(TreeScope.Children, condTabItem))
    {
        // HERE IS YOUR TABS!!!!
        ret.Add(tabitem.Current.Name);
    }
    

    【讨论】:

      【解决方案2】:

      我最近用 System.Windows.Forms.SendKeys 解决了同样的问题 与您的结果相比 - 它快 4 倍,但不适用于使用 ctrl+l 热键的网站(例如编辑模式下的 StackOwerflow)。 取决于你的需要:)

       public void WithSendkeys()
          {
              AutomationElement.RootElement
                  .FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "Chrome_WidgetWin_1"))
                  .SetFocus();
              SendKeys.SendWait("^l");
              var elmUrlBar = AutomationElement.FocusedElement;
              var valuePattern = (ValuePattern) elmUrlBar.GetCurrentPattern(ValuePattern.Pattern);
              Console.WriteLine(valuePattern.Current.Value);
          }
      

      【讨论】:

        【解决方案3】:

        此代码适用于我并获取 chrome 的活动标签的 URL

         Process[] procsChrome = Process.GetProcessesByName("chrome");
                    foreach (Process chrome in procsChrome)
                    {
                        // the chrome process must have a window
                        if (chrome.MainWindowHandle == IntPtr.Zero)
                        {
                            continue;
                        }
        
                        // find the automation element
                        AutomationElement elm = AutomationElement.FromHandle(chrome.MainWindowHandle);
                        AutomationElement elmUrlBar = elm.FindFirst(TreeScope.Descendants,
                          new PropertyCondition(AutomationElement.NameProperty, "Address and search bar"));
        
                        // if it can be found, get the value from the URL bar
                        if (elmUrlBar != null)
                        {
                            AutomationPattern[] patterns = elmUrlBar.GetSupportedPatterns();
                            if (patterns.Length > 0)
                            {
                                ValuePattern val = (ValuePattern)elmUrlBar.GetCurrentPattern(patterns[0]);
                                Console.WriteLine("Chrome URL found: " + val.Current.Value);
                                listbox.Items.Add(val.Current.Value);
                            }
                        }
                    }
        

        【讨论】:

        • 对于希望在不包含本地化文本“地址和搜索栏”的情况下执行此操作的任何人,它(当前)适用于 elmUrlBar = elm.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
        猜你喜欢
        • 2013-04-17
        • 2019-03-11
        • 2019-07-19
        • 1970-01-01
        • 2018-03-07
        • 2012-01-09
        • 2018-06-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多