Search code examples
c#.netpowershellcomole

How to get a reference to an IWebBrowser object


I'm writing a script in Powershell that will open a series of tabs for me and log in to each tab that is opened. So far my script is pretty standard.

$ipaddresses = #some array of ip addresses
$ie = New-Object -ComObject internetexplorer.application
$ie.Visible = $true
for ($i = 0; $i -lt 1; $i++) {
    $url = "http://"+($ipaddresses[$i])+":8000"
    if($i -eq 0) {$ie.Navigate($url+"/login",0)} else {$ie.Navigate($url+"/login",2048)}
    while($ie.Document.readyState -ne "complete") { Start-Sleep -Milliseconds 100 }
    $ie.Document.getElementById("submitButton").click()
    while($ie.Document.readyState -ne "complete") { Start-Sleep -Milliseconds 100 }
}

My biggest problem is that whenever the navigate method is called, my reference to my new tab is lost and the reference to my existing tab is still used. The new tab is created and it navigates to the right page, but the calls to Document.readyState and Document.getElementByID().click() are being called on my first tab throughout the for loop. I investigated this and I found that this behavior is documented in the Navigate method in MSDN https://msdn.microsoft.com/en-us/library/aa752093(v=vs.85).aspx.

When navOpenInNewWindow or navOpenInNewTab is specified, the caller does not receive a reference to the WebBrowser object for the new window, so there is no immediate way to manipulate it.

So, given that I cannot get a reference to my new web browser object through the Navigate method I need to get a reference to it another way.

How do I get a reference to a new WebBrowser object?

For reference, I've looked at the InternetExplorer object documentation, https://msdn.microsoft.com/en-us/library/aa752084(v=vs.85).aspx, and the WebBrowser control documentation, https://msdn.microsoft.com/en-us/library/w290k23d(v=vs.110).aspx and a solution is still not immediately apparent to me.


Solution

  • So, i made it my mission to figure this out and admittedly it wasnt easy, but i have a solution that works.

    $windows = (New-Object -ComObject Shell.Application).Windows()
    $ie = New-Object -ComObject internetexplorer.application
    $ie.Visible = $true
    $ie.Navigate("http://www.taylorgibb.com", 0)
    $ie.Navigate("https://stackoverflow.com/questions/tagged/powershell", 2048)
    
    while($ie.Busy) { 
        Start-Sleep -Milliseconds 100 
    }
    
    $tabs = $windows | Where {$_.Name -eq "Internet Explorer" -and $_.HWND -eq $ie.HWND}
    $button = $tabs[1].Document.IHTMLDocument2_all | where {$_.id -eq 'nav-jobs'}
    $button.click()
    

    Using the shell allows us to get access to the tab via index, since you opening your tabs from a predefined array, you already have a mapping between the site URL and its index.