Binding To An Existing Internet Explorer Instance

In my post

you saw that when automating Internet Explorer, we cannot use GetObject to bind to an existing instance.

So what is one to do exactly, if the wish to do so anyways?

In fact, I kind of already gave the solution in my article

Where we iterate over a collection of windows until we find what we are looking for.

Binding To An Existing Instance Of Internet Explorer

Over the years, I perfected my original code slightly, so here is a more versatile function you can use to return an IE object that you can then continue to use in your code.

Function IE_GetoIE(Optional ByVal sUrl As String, _
                   Optional ByVal sTitle As String, _
                   Optional ByVal bCreateNewInstance As Boolean = False) As Object
    On Error GoTo Error_Handler
    Dim oShell                As Shell32.Shell 'Ref: Microsoft Shell Controls And Automation
    Dim oWindows              As SHDocVw.ShellWindows 'Ref: Microsoft Internet Controls
    Dim oWindow               As SHDocVw.InternetExplorer 'Ref: Microsoft Internet Controls
    Dim bWindowFound          As Boolean

    If bCreateNewInstance = False Then
        Set oShell = CreateObject("Shell.Application")
        Set oWindows = oShell.Windows

        For Each oWindow In oWindows
            If Not oWindow Is Nothing Then
                If (InStr(1, oWindow, "Internet Explorer", vbTextCompare)) Then
                    If sUrl = "" And sTitle = "" And oWindow.LocationURL <> "" Then
                        bWindowFound = True
                    ElseIf sUrl <> "" Then
                        If LCase(oWindow.LocationURL) = LCase(sUrl) Then
                            bWindowFound = True
                        End If
                    ElseIf sTitle <> "" Then
                        If LCase(oWindow.LocationName) = LCase(sTitle) Then
                            bWindowFound = True
                        End If
                    End If
                    If bWindowFound = True Then
                        Set IE_GetoIE = oWindow
                        Exit For
                    End If
                End If
            End If
        Next oWindow
    End If

    If IE_GetoIE Is Nothing Then Set IE_GetoIE = CreateObject("InternetExplorer.Application")

Error_Handler_Exit:
    On Error Resume Next
    If Not oWindow Is Nothing Then Set oWindow = Nothing
    If Not oWindows Is Nothing Then Set oWindows = Nothing
    If Not oShell Is Nothing Then Set oShell = Nothing
    Exit Function

Error_Handler:
    MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: " & sModName & "\IE_GetoIE" & vbCrLf & _
           "Error Description: " & Err.Description & _
           Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
           , vbOKOnly + vbCritical, "An Error has Occured!"
    Resume Error_Handler_Exit
End Function

It can either:

  • Create a new instance
  • Find an existing instance by URL
  • Find an existing instance by title

Usage Example

Let’s take it for a drive then. Let’s say we want to extract some information about my article

Then you can do something like

Sub TestoIE()
    Dim oIE                   As SHDocVw.InternetExplorer    'Ref: Microsoft Internet Controls
    Dim oHTMLDoc              As Object
    Const sURL                As String = "https://www.devhut.net/avoiding-the-followhyperlink-security-warning/"

    Set oIE = IE_GetoIE(sURL)
    If oIE.LocationURL = "" Then
        With oIE
            .Navigate sURL
            .Visible = True    'Make false in production?
            Do While .Busy Or .ReadyState <> 4: DoEvents: Loop
        End With
    End If

    Set oHTMLDoc = oIE.Document
    
    Debug.Print "Title", IE_GetTitle(oHTMLDoc)    'can also simply use oIE.LocationName
    Debug.Print "Description", IE_GetMetaContent(oHTMLDoc, "Description")
    Debug.Print "Robots", IE_GetMetaContent(oHTMLDoc, "Robots")
    Debug.Print "Keywords", IE_GetMetaContent(oHTMLDoc, "Keywords")
    Debug.Print "Generator", IE_GetMetaContent(oHTMLDoc, "Generator")
    Debug.Print "Test", IE_GetMetaContent(oHTMLDoc, "Test")

    If Not oHTMLDoc Is Nothing Then Set oHTMLDoc = Nothing
    If Not oIE Is Nothing Then Set oIE = Nothing
End Sub

If there is an instance running with that URL open, it will bind to it and use it, otherwise it will create a new instance and navigate to the URL.

Helper Functions

The Sub TestoIE uses the following helper functions:

Function IE_GetTitle(ByVal oHTMLDoc As Object) As String
    Dim TitleElements As Object
    
    Set TitleElements = oHTMLDoc.getElementsByTagName("title")
    If TitleElements.length > 0 Then
        IE_GetTitle = TitleElements(0).innerHTML
    End If
    
    If Not TitleElements Is Nothing Then Set TitleElements = Nothing
End Function

Function IE_GetMetaContent(ByVal oHTMLDoc As Object, ByVal sMetaName As String) As String
    Dim MetaElements As Object
    Dim MetaElement As Object
    
    IE_GetMetaContent = "***META NOT FOUND***"
    
    Set MetaElements = oHTMLDoc.getElementsByTagName("meta")
    For Each MetaElement In MetaElements
        If LCase(MetaElement.Name) = LCase(sMetaName) Then
            IE_GetMetaContent = MetaElement.content
            Exit For
        End If
    Next
    
    If Not MetaElement Is Nothing Then Set MetaElement = Nothing
    If Not MetaElements Is Nothing Then Set MetaElements = Nothing
End Function

So as you can see, you now have a single function that can both bind to existing instances and create new ones. Best of both worlds.

A Few Resources on the Subject

One response on “Binding To An Existing Internet Explorer Instance

  1. mos kah

    my approach was all the time to make a form that has an internet explorer inside, so always refer to this form and the web element, wouldn’t it be the same?