Making Invisible Internet Explorer Instances Visible

While investigating behavior I had previously documented in which SuperAntiSpyware spawns hidden iexplore.exe processes. Rather than terminating them blindly, I wanted a way to make every existing Internet Explorer instance visible so I could see exactly what was going on.

Internet Explorer is not just a browser. It is also a COM automation server. This allows applications, scripts, and services to create Internet Explorer instances in the background for tasks such as report generation, authentication flows, or legacy system integrations. When those instances are created with their visibility turned off, or are never explicitly shown, they can remain running long after their original purpose has passed.

Task Manager will show the process, but it offers no insight into why it exists or what it is doing. Ending the process may remove the symptom, but it does not explain the behavior and can potentially disrupt the software that created it.

What I wanted was simple.

If Internet Explorer is running, I wanted to see it, see what it was up to.
 

My Goal: Force All Hidden Internet Explorer Instances to Appear

Instead of guessing or terminating processes at random, I focused on visibility. If an Internet Explorer instance exists and has a user interface, it should be visible on screen so its activity can be examined directly.

Windows already provides the necessary tools through COM automation. By using the Shell Application object, it is possible to enumerate all shell windows, including Internet Explorer instances that were created invisibly.
 

Failed Attempt: GetObject

An obvious first thought is to use GetObject to attach to a running Internet Explorer instance. While this works for a single IE process, it quickly fails when multiple instances exist. GetObject always attaches to the first registered COM instance and ignores the rest, so it is not suitable for revealing all hidden windows.

Sub IE_ShowInstance_GetObject()
    On Error Resume Next

    Dim ie As Object
    Set ie = GetObject(, "InternetExplorer.Application")

    If Not ie Is Nothing Then
        ie.Visible = True
    End If
End Sub

This approach is limited because if multiple IE processes are running, only one is revealed, leaving other hidden instances unseen. For a comprehensive solution, enumerating all shell windows is required.

In my case, nothing was revealed when I ran this procedure, so I kept digging.
 

The Solution: Enumerating Shell Windows

I remembered I had long ago posted about ‘Binding To An Existing Internet Explorer Instance‘. I took that articles code as a great starting point and within a minute I was operational.

Here’s the resulting VBA procedure:

Public Sub IE_ShowInstances()
    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

    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
                oWindow.Visible = True
            End If
        End If
    Next oWindow

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 Sub

Error_Handler:
    MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
           "Error Number: " & Err.Number & vbCrLf & _
           "Error Source: IE_ShowInstances" & 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 Sub

 

How It Works

In practical terms, this procedure performs the following actions.

  1. Retrieves the system shell window collection
  2. Iterates through each shell managed window
  3. Identifies Internet Explorer instances
  4. Forces each instance to become visible

If an Internet Explorer process exists and is capable of displaying a user interface, it will appear on screen.
 

Final Thoughts

Internet Explorer may be deprecated, but in legacy environments it continues to be used. Hidden instances can consume system resources, complicate debugging efforts, or raise legitimate questions about background activity and system security.

Instead of terminating processes and hoping for the best, forcing them into view provides clarity and context.

If something is running on your machine, it should be able to show itself. I’ve never understood why Microsoft never provided a means via the Task Manager to make a process visible and bring it to the front (obviously when possible).