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.
- Retrieves the system shell window collection
- Iterates through each shell managed window
- Identifies Internet Explorer instances
- 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).