Перечислить URL-адрес Chrome на всех открытых вкладках vb.net

Я пытаюсь перечислить и получить URL-адреса всех открытых вкладок в Chrome. С большой помощью Google (ну... на самом деле из Stackoverflow :-)) мне удалось перечислить и получить «Имена» всех открытых вкладок, используя приведенный ниже код.

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

И, используя приведенный ниже код, я могу получить URL-адрес выбранной «активной» вкладки в браузере Chrome.

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-адреса всех открытых вкладок, а не только имена, как это делается с помощью первого кода выше. Любая помощь будет очень полезна. Заранее спасибо :-)

Я перепробовал все примеры и методы в приведенном ниже сообщении, и, похоже, это не дало правильных результатов.

сообщение Stackoverflow похоже на этот пост

С уважением,

Сен


person Kumsen    schedule 10.02.2017    source источник


Ответы (1)


Вы можете относительно легко получить значение поля адреса. Что-то в этом роде будет работать:

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)

Это даст вам URL-адрес текущей выбранной вкладки. Примечание. Существует только одно адресное поле для всех вкладок — значение в этом поле меняется по мере того, как пользователь выбирает каждую вкладку (т. е. нет отдельного адресного поля для каждой вкладки).

Вы можете выбрать каждую вкладку, а затем взять значение из поля адреса. Что-то вроде этого должно работать:

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. Кажется, здесь есть связанный вопрос: Доступность управляющего шаблона имеет значение true, но возвращает исключение «Неподдерживаемый шаблон».

Вы также можете использовать 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
person theduck    schedule 10.02.2017
comment
Не могу запустить вторую часть. Я получаю сообщение об ошибке Ошибка 1 'elemTabStrip' не объявлен. Он может быть недоступен из-за его уровня защиты. Я понимаю, что декларация нужна... но не могу понять, как ее определить. - person Kumsen; 15.02.2017
comment
Я использовал тот же код, что и ваша функция FindChromeTabsURL. Он определяет elemTabStrip (который содержит каждую из вкладок) - person theduck; 15.02.2017
comment
ОтправитьКлючи! этот метод сработал отлично .. большое спасибо :-) - person Kumsen; 22.03.2017