在所有打开的选项卡中枚举 Chrome URL vb.net

Enumerate Chrome URL in all open tabs vb.net

我正在尝试枚举并获取 chrome 中所有打开的选项卡的 URL。在 google 的大量帮助下(好吧..实际上来自 Whosebug :-))我可以使用下面的代码设法枚举并获取所有打开的选项卡的 "Names"..

Imports System.Windows.Automation
Imports System.Runtime.InteropServices
Imports System.Text

Public Class Form1

    Public Declare Auto Function GetClassName Lib "User32.dll" (ByVal hwnd As IntPtr, _
    <Out()> ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer

    Public Delegate Function CallBack(ByVal hwnd As Integer, ByVal lParam As Integer) As Boolean
    Public Declare Function EnumWindows Lib "user32" (ByVal Adress As CallBack, ByVal y As Integer) As Integer
    Public Declare Function IsWindowVisible Lib "user32.dll" (ByVal hwnd As IntPtr) As Boolean

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        GetActiveWindows()
    End Sub

    Public Sub GetActiveWindows()
        EnumWindows(AddressOf Enumerator, 0)
    End Sub

    Private Function Enumerator(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
        '//Only active windows
        If IsWindowVisible(hwnd) Then
            Dim sClassName As New StringBuilder("", 256)
            GetClassName(hwnd, sClassName, 256)
            '//Only want visible chrome windows
            If sClassName.ToString = "Chrome_WidgetWin_1" Then
                FindChromeTabsURL(hwnd)
            End If
        End If
        Return True
    End Function

    Private Sub FindChromeTabs(hwnd As IntPtr)

        '//To find the tabs we first need to locate something reliable - the 'New Tab' button
        Dim rootElement As AutomationElement = AutomationElement.FromHandle(hwnd)
        Dim condNewTab As Condition = New PropertyCondition(AutomationElement.NameProperty, "New Tab")

        '//Find the 'new tab' button
        Dim elemNewTab As AutomationElement = rootElement.FindFirst(TreeScope.Descendants, condNewTab)

        '//No tabstrip found
        If elemNewTab = Nothing Then Exit Sub

        '//Get the tabstrip by getting the parent of the 'new tab' button
        Dim tWalker As TreeWalker = TreeWalker.ControlViewWalker
        Dim elemTabStrip As AutomationElement = tWalker.GetParent(elemNewTab)

        '//Loop through all the tabs and get the names which is the page title
        Dim tabItemCondition As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TabItem)
        For Each tabItem As AutomationElement In elemTabStrip.FindAll(TreeScope.Children, tabItemCondition)
            Debug.WriteLine(tabItem.Current.Name)
        Next

    End Sub

    Private Sub FindChromeTabsURL(ByVal hwnd As IntPtr)

        '//To find the tabs we first need to locate something reliable - the 'New Tab' button
        Dim rootElement As AutomationElement = AutomationElement.FromHandle(hwnd)
        Dim condNewTab As Condition = New PropertyCondition(AutomationElement.NameProperty, "New Tab")

        'retURL(hwnd)
        'Exit Sub

        '//Find the 'new tab' button
        Dim elemNewTab As AutomationElement = rootElement.FindFirst(TreeScope.Descendants, condNewTab)

        '//No tabstrip found
        If elemNewTab = Nothing Then Exit Sub

        '//Get the tabstrip by getting the parent of the 'new tab' button
        Dim tWalker As TreeWalker = TreeWalker.ControlViewWalker
        Dim elemTabStrip As AutomationElement = tWalker.GetParent(elemNewTab)

        '//Loop through all the tabs and get the names which is the page title
        Dim tabItemCondition As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TabItem)
        For Each tabItem As AutomationElement In elemTabStrip.FindAll(TreeScope.Children, tabItemCondition)
            Debug.WriteLine(tabItem.Current.Name)
        Next


    End Sub

并使用下面的代码,我能够在 chrome 浏览器中获取所选 "active" 选项卡的 URL。

Dim procsChrome As Process() = Process.GetProcessesByName("chrome")
For Each chrome As Process In procsChrome
    If chrome.MainWindowHandle = IntPtr.Zero Then Continue For

    Dim elm As AutomationElement = AutomationElement.FromHandle(hwnd)
    Dim elmUrlBar As AutomationElement = elm.FindFirst(TreeScope.Descendants, New PropertyCondition(AutomationElement.NameProperty, "Address and search bar"))


    If elmUrlBar IsNot Nothing Then
        Dim patterns As AutomationPattern() = elmUrlBar.GetSupportedPatterns()
        If patterns.Length > 0 Then
            Dim val As ValuePattern = DirectCast(elmUrlBar.GetCurrentPattern(patterns(0)), ValuePattern)
            If Not elmUrlBar.GetCurrentPropertyValue(AutomationElement.HasKeyboardFocusProperty) Then MsgBox(LCase(val.Current.Value).Trim)
            'Exit For
        End If
    End If
Next

我无法弄清楚如何获取所有打开的选项卡的 URL 而不是像第一个代码那样仅获取名称 above.Any 帮助将非常有用..谢谢提前:-)

我已经尝试了下面的所有示例和方法post,但似乎没有产生正确的结果..

Whosebug post similar to this post

此致,

您可以比较容易地获取地址框的值。这些方面的东西会起作用:

Dim rootElement As AutomationElement = AutomationElement.FromHandle(hwnd)

Dim addressCondition As Condition = New PropertyCondition(AutomationElement.NameProperty, "Address and search bar")
Dim addressBar = rootElement.FindFirst(TreeScope.Descendants, addressCondition)
Debug.WriteLine(addressBar.GetCurrentPattern(ValuePattern.Pattern).Current.Value)

这将为您提供当前 select 选项卡的 URL。注意:所有选项卡只有一个地址框 - 框中的值随着用户 select 每个选项卡的变化而变化(即每个选项卡没有单独的地址框)。

您可以 select 每个选项卡,然后从地址框中获取值。这样的事情应该有效:

Dim tabItemCondition As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TabItem)
For Each tabItem As AutomationElement In elemTabStrip.FindAll(TreeScope.Children, tabItemCondition)

    Dim selectionItemPattern As SelectionItemPattern = tabItem.GetCurrentPattern(SelectionItemPattern.Pattern)
    selectionItemPattern.Select()

    ... (Grab the address box value here)

Next

在 Chrome 55 上快速尝试此操作对我没有用,并抛出一个错误,指出不支持 SelectionItem 模式,即使它使用 Inspect.exe 显示为可用。这里似乎有一个相关的问题:Control pattern availability is set to true but returns `Unsupported pattern.` exception

您还可以使用 SendKeys 在选项卡中移动。在代码开头添加以下声明:

Private Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As IntPtr) As Boolean

然后你的 FindChromeTabsURL() 看起来像这样:

Private Sub FindChromeTabsURL(ByVal hwnd As IntPtr)
    Dim rootElement As AutomationElement = AutomationElement.FromHandle(hwnd)
    Dim condNewTab As Condition = New PropertyCondition(AutomationElement.NameProperty, "New Tab")
    Dim elemNewTab As AutomationElement = rootElement.FindFirst(TreeScope.Descendants, condNewTab)
    If elemNewTab = Nothing Then Exit Sub

    '//Get the tabstrip by getting the parent of the 'new tab' button
    Dim tWalker As TreeWalker = TreeWalker.ControlViewWalker
    Dim elemTabStrip As AutomationElement = tWalker.GetParent(elemNewTab)

    SetForegroundWindow(hwnd)
    Dim addressCondition As Condition = New PropertyCondition(AutomationElement.NameProperty, "Address and search bar")
    Dim addressBar = rootElement.FindFirst(TreeScope.Descendants, addressCondition)

    Dim tabItemCondition As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TabItem)
    For Each tabItem As AutomationElement In elemTabStrip.FindAll(TreeScope.Children, tabItemCondition)
        SendKeys.Send("^{TAB}")
        Debug.WriteLine(addressBar.GetCurrentPattern(ValuePattern.Pattern).Current.Value)
    Next

End Sub