I'm trying to retrieve all the urls that are open in the Firefox tabs.
This is what I've done so far, the code gets all the Firefox urls, yes, but it also retrieves all the urls from each open document, for example embedded youtube urls from forums, etc... things that I'm not interested.
How I can fix that?.
And also it throws an exception
A first chance exception of type 'System.InvalidOperationException' occurred in Microsoft.VisualBasic.dll
when trying to cast as String here:
test.Add(TryCast(DirectCast(d.GetCurrentPattern(ValuePattern.Pattern), ValuePattern).Current.Value, String))
...but I suppose that problem should be solved if I can "filter" properly the controls to retrieve the proper urls.
Also another problem of this code, the UI Automation makes my Firefox process unminizable from Taskbar, I can't press the Firefox taskbar button to maximize/minimize the window after running these UI Automation instructions.
Imports System.Windows.Automation
Public Shared Function GetFirefoxUrls(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
Dim docs As AutomationElementCollection =
element.FindAll(TreeScope.Subtree,
New PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document))
If docs Is Nothing Then
Return Nothing
Else
Dim test As New List(Of String)
For Each d In docs
Try
test.Add(TryCast(DirectCast(d.GetCurrentPattern(ValuePattern.Pattern), ValuePattern).Current.Value, String))
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
Next
Return test
End If ' doc Is Nothing
End If ' element Is Nothing
End If ' process Is Nothing
End Function
Usage:
Dim urls As List(Of String) =
GetFirefoxUrls(Process.GetProcessesByName("Firefox").First)
Using the Inspect tool (it's in the Windows 7 SDK), I see that all of the Firefox tabs' URL EditControls have the Name="Search or enter address". I don't recall that you can create a PropertyCondition based on the element's Name (I don't believe you can). But as you iterate over the Document elements, could you get the Name property of each and compare against "Search or enter address" before you add them to your list? --i.e., right before this line of code:
test.Add(TryCast(DirectCast(d.GetCurrentPattern(ValuePattern.Pattern), ValuePattern).Current.Value, String))
[EDIT] Oops please disregard, spoke too soon. The Name="Search or enter address" EditControl is just a control within the Navigation Toolbar parent...it's contains the current tab's URL, not the URL of each page.
Plan B: Can you build a test app which iterates over the entire document and compares ValueProperty values agains known URL text fragments fragments in your Firefox test session--strings like "http://"? Then see what attributes those elements have in common with other URL-containing elements--maybe a common parent name, etc.