Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

.NET 

Get FF Tabs - Solved, answer in OP

So I have the following code to get all firefox tabs, but it's fairly slow:
Code
Dim con As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document)
Dim tw As New TreeWalker(con)
Dim child As AutomationElement = tw.GetFirstChild(element)
While Not IsNothing(child)
    Try
        Dim url As String = DirectCast(child.GetCurrentPattern(ValuePattern.Pattern), ValuePattern).Current.Value.ToString
        child = tw.GetNextSibling(child)
        MsgBox(url)
    Catch ex As Exception
        MsgBox(ex.ToString)
        Exit While
    End Try
End While

After some research, I found that FindAll is meant to be quicker, so I replaced it with this:
Code
Dim con As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document)
Dim children As AutomationElementCollection = element.FindAll(TreeScope.Children, con)
For Each child As AutomationElement In children
    Try
        Dim url As String = DirectCast(child.GetCurrentPattern(ValuePattern.Pattern), ValuePattern).Current.Value.ToString
        MsgBox(url)
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
Next
However the children array count returns 0, so I tried this:

Code
Dim children As AutomationElementCollection = element.FindAll(TreeScope.Children, Condition.TrueCondition)
For Each child As AutomationElement In children
    Try
        Dim url As String = DirectCast(child.GetCurrentPattern(ValuePattern.Pattern), ValuePattern).Current.Value.ToString
        MsgBox(url)
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
Next
And got 29 children, but all of them threw an invalid patter error.

Am I missing something, or is there another faster alternative to the TreeWalker?

Thanks in advance, Josh


So after hours of fucking about, I got this and it's much quicker (the aim of the program is to get youtube tabs):
Code
Private Function GetFirefoxTabs(process As Process) As List(Of String)
    If process Is Nothing Then
        Throw New ArgumentNullException("process")
    ElseIf process.MainWindowHandle = IntPtr.Zero Then
        Throw New ArgumentException("Invalid process.", "process")
    Else
        Dim element As AutomationElement = AutomationElement.FromHandle(process.MainWindowHandle)
        If element Is Nothing Then
            Return Nothing
        Else
            Try
                Dim con As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Custom)
                Dim docCon As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document)
                Dim imageCon As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Image)
                Dim children As AutomationElementCollection = element.FindAll(TreeScope.Children, con)
                Dim root As AutomationElement = Nothing
                For Each child As AutomationElement In children
                    Dim items As AutomationElementCollection = child.FindAll(TreeScope.Children, Condition.TrueCondition)
                    If items.Count > 1 Then
                        If IsNothing(child.FindFirst(TreeScope.Children, imageCon)) Then
                            root = child
                            Exit For
                        End If
                    End If
                Next
                For Each child As AutomationElement In root.FindAll(TreeScope.Children, Condition.TrueCondition)
                    Dim childChildren As AutomationElementCollection = child.FindAll(TreeScope.Children, Condition.TrueCondition)
                    For Each item As AutomationElement In childChildren
                        Dim documents As AutomationElementCollection = item.FindAll(TreeScope.Children, docCon)
                        For Each doc As AutomationElement In documents
                            Dim title As String = doc.Current.Name
                            If Not String.IsNullOrWhiteSpace(title) Then title = Web.HttpUtility.HtmlDecode(title)
                            If Not String.IsNullOrWhiteSpace(title) AndAlso title.EndsWith(" - YouTube") Then FFTabs.Add(title.Substring(0, title.LastIndexOf(" - YouTube")).Trim)
                        Next
                    Next
                Next
            Catch ex As Exception
                MsgBox(ex.ToString)
            End Try
        End If ' element Is Nothing
    End If ' process Is Nothing
    Return FFTabs
End Function


After some more messing about, here's I think the final edit to get all windows:
Code
Private Declare Auto Function GetClassName Lib "User32.dll" (ByVal hwnd As IntPtr, <Out()> ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer

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

Private FFTabs As New List(Of String)

Private Function GetFFTabs() As List(Of String)
    FFTabs.Clear()
    EnumWindows(AddressOf FirefoxEnumerator, 0)
    Return FFTabs
End Function

Private Function FirefoxEnumerator(ByVal hwnd As IntPtr, ByVal lParam As Integer) As Boolean
    If IsWindowVisible(hwnd) Then
        Dim sClassName As New StringBuilder("", 256)
        GetClassName(hwnd, sClassName, 256)
        If sClassName.ToString = "MozillaWindowClass" Then
            FindFirefoxTabs(hwnd)
        End If
    End If
    Return True
End Function

Private Sub FindFirefoxTabs(hwnd As IntPtr)
    Dim element As AutomationElement = AutomationElement.FromHandle(hwnd)
    Try
        Dim con As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Custom)
        Dim docCon As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document)
        Dim imageCon As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Image)
        Dim children As AutomationElementCollection = element.FindAll(TreeScope.Children, con)
        Dim root As AutomationElement = Nothing
        For Each child As AutomationElement In children
            Dim items As AutomationElementCollection = child.FindAll(TreeScope.Children, Condition.TrueCondition)
            If items.Count > 1 Then
                If IsNothing(child.FindFirst(TreeScope.Children, imageCon)) Then
                    root = child
                    Exit For
                End If
            End If
        Next
        For Each child As AutomationElement In root.FindAll(TreeScope.Children, Condition.TrueCondition)
            Dim childChildren As AutomationElementCollection = child.FindAll(TreeScope.Children, Condition.TrueCondition)
            For Each item As AutomationElement In childChildren
                Dim documents As AutomationElementCollection = item.FindAll(TreeScope.Children, docCon)
                For Each doc As AutomationElement In documents
                    Dim title As String = doc.Current.Name
                    If Not String.IsNullOrWhiteSpace(title) Then title = Web.HttpUtility.HtmlDecode(title)
                    If Not String.IsNullOrWhiteSpace(title) AndAlso title.EndsWith(" - YouTube") Then FFTabs.Add(title.Substring(0, title.LastIndexOf(" - YouTube")).Trim)
                Next
            Next
        Next
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub
+1 for putting fixed code in OP instead of deleting thread.
edit: had one on you, sorry! :)
Final update I think, just made some changes to the FindFirefoxTabs method:
Code
Private Sub FindFirefoxTabs(hwnd As IntPtr)
    Dim element As AutomationElement = AutomationElement.FromHandle(hwnd)
    Try
        Dim con As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Custom)
        Dim docCon As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document)
        Dim imageCon As Condition = New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Image)
        Dim children As AutomationElementCollection = element.FindAll(TreeScope.Children, con)
        For Each child As AutomationElement In children
            Dim items As AutomationElementCollection = child.FindAll(TreeScope.Children, Condition.TrueCondition)
            If items.Count >= 1 Then
                If IsNothing(child.FindFirst(TreeScope.Children, imageCon)) Then
                    Dim root As AutomationElement = child
                    For Each child2 As AutomationElement In root.FindAll(TreeScope.Children, Condition.TrueCondition)
                        Dim childChildren As AutomationElementCollection = child2.FindAll(TreeScope.Children, Condition.TrueCondition)
                        For Each item As AutomationElement In childChildren
                            Dim documents As AutomationElementCollection = item.FindAll(TreeScope.Children, docCon)
                            For Each doc As AutomationElement In documents
                                Dim title As String = doc.Current.Name
                                If Not String.IsNullOrWhiteSpace(title) Then title = Web.HttpUtility.HtmlDecode(title)
                                If Not String.IsNullOrWhiteSpace(title) AndAlso title.EndsWith(" - YouTube") Then FFTabs.Add(title.Substring(0, title.LastIndexOf(" - YouTube")).Trim)
                            Next
                        Next
                    Next
                End If
            End If
        Next
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub


Possibly Related Threads...
Thread / Author Replies Views Last Post
[.NET] by PrillorFeb 6, 2017 10:25 AM 4 266 Feb 6, 2017 10:25 AM
Last Post: Prillor
[.NET] by pakalupapitoNov 29, 2015 04:19 AM 16 480 Nov 29, 2015 04:19 AM
Last Post: He B TeMy
[.NET] by Lexxi.Jul 1, 2015 02:20 AM 4 131 Jul 1, 2015 02:20 AM
Last Post: Lexxi.