Page 1 of 1

COM, use existing Internet Explorer?

Posted: 10 Feb 2015, 12:16
by TheDewd
How can I interact with an existing Internet Explorer window using COM?

All the information I can find is for ComObjCreate, not ComObjActive, when working with Internet Explorer. Any ideas?

Internet Explorer 11 on Windows 7.

Re: COM, use existing Internet Explorer?

Posted: 10 Feb 2015, 12:23
by kon ... -tutorial/
- See the part marked "How to access an existing IE object?"

Re: COM, use existing Internet Explorer?

Posted: 11 Feb 2015, 16:20
by atnbueno
I experimented a bit with this a couple of years ago. In case it serves as example/inspiration, here's the code:

Code: Select all

; AutoHotkey_L Version: (Unicode x86)
; Language:             English
; Platform:             Win7 SP1
; Author:               Antonio Bueno <user atnbueno at Google's free e-mail service>
; Description:          Experiments on interacting with an existing Internet Explorer window
; Last Mod:             2012-10-25

; initial configuration
FileEncoding, UTF-8
SetWorkingDir %A_ScriptDir%
SplitPath, A_ScriptName, , , , ScriptBasename
StringReplace, AppTitle, ScriptBasename, _, %A_SPACE%, All

; Functions to log and notify what's happening
Log(Message, Type=1) ; Type=1 shows an info icon, Type=2 a warning one, and Type=3 an error one
	global ScriptBasename, AppTitle
	IfEqual, Type, 2
		Message = WARNING: %Message%
	IfEqual, Type, 3
		Message = ERROR: %Message%
	FileAppend, %A_YYYY%-%A_MM%-%A_DD% %A_Hour%:%A_Min%:%A_Sec%.%A_MSec%%A_Tab%%Message%`n, %ScriptBasename%.log
	Type += 16
	TrayTip, %AppTitle%, %Message%, , %Type%
	SetTimer, HideTrayTip, 1000
	SetTimer, HideTrayTip, Off
LogAndExit(message, Type=1)
	global ScriptBasename
	Log(message, Type)
	FileAppend, `n, %ScriptBasename%.log
	Sleep 1000

Log("Script starts")

ShellWindowCount := ComObjCreate("Shell.Application").Windows.Count ; Determines how many shell windows exist

if (ShellWindowCount > 0)
	Log("Shell windows found: " . ShellWindowCount)
	for IEobj in ComObjCreate("Shell.Application").Windows
		; each IEobj is an Internet Explorer object (in case of tabbed windows, one object per tab)
		; see
		; IEobj.LocationName is the window title
		; IEobj.LocationURL is the URI (can be empty)
		; IEobj.FullName is the full path to either Explorer.EXE or iexplore.exe (both 32 and 64-bit)
		Log("LocationName: " . IEobj.LocationName . "; LocationURL: " . IEobj.LocationURL . "; FullName: " . IEobj.FullName)
		if (SubStr(IEobj.FullName, -12) = "\iexplore.exe")
			IE := IEobj
	if IE ; if an Internet Explorer window is found
		Log("Internet Explorer window found. Current URL is " . IE.LocationURL)
		ComObjConnect(IE, "IE_") ; connects the "IE_*" functions to the "IE" object
		IE_OnQuit() {
			Log("Internet Explorer window closed")
		; HACK: adds jQuery to initial webpage
		IE.Navigate("javascript:void(function(){var jQscript=document.createElement('script');jQscript.src='';document.documentElement.appendChild(jQscript);}());")
		; HACK: shows jQuery works
		IE.Navigate("javascript:void(function(){$('body').css('border', '4px solid red')}())")
		lastURL := ""
		loop ; repeats this until the IE window or the script is closed
			if (IE.LocationURL <> lastURL)
				Log("New URL is " . IE.LocationURL)
				lastURL := IE.LocationURL
				while IE.Busy
					Sleep 100
				; converts URL to filename
				StringTrimLeft, filename, lastURL, 7 ; http://
				StringReplace, filename, filename, /, -, All
				StringReplace, filename, filename, ?, _, All
				StringReplace, filename, filename, &, _, All
				filename .= .html
				; saves page source to file
				source := IE.Document.documentElement.innerHTML
				FileDelete, %filename%
				FileAppend, %source%, %filename%
				Log("Page source (" . StrLen(source) . " bytes) saved to " . filename)
	} else {
		Log("Didn't find any Internet Explorer windows")
		MsgBox, Didn't find any Internet Explorer window (nothing to do)
} else {
	Log("Didn't find any shell windows")
	MsgBox, Didn't find any shell windows (nothing to do)

LogAndExit("Script ends")

Re: COM, use existing Internet Explorer?

Posted: 11 Feb 2015, 19:30
by jethrow
WARNING - off topic ... kinda
atnbueno wrote:I experimented a bit with this a couple of years ago. In case it serves as example/inspiration ...
Though your code that is relevant to the OP can be found in the link provided by kon, you do provide a nice example of using jQuery:

Code: Select all

; Set Vars
IID := "{332C4427-26CB-11D0-B483-00C04FD90119}"   ;// IID_IHTMLWindow2
Windows := ComObjCreate("Shell.Application").Windows()
ieCount := Windows.Count

; Launch IE
Run, iExplore.exe, , , pid
WinWait ahk_pid %pid%
WinGet, hwnd, ID, ahk_pid %pid%

; Wait for IE to get added to the Shell.Application.Windows collection
while ieCount = Windows.Count
    sleep 10

; Get IE
for ie in Windows
    if (ie.hwnd = hwnd)
        ie := ""
if Not ie {
    MsgBox Error

; Wait for IE to load
while ie.busy
    sleep 100

; Insert jQuery
jQscript := ie.document.createElement("script")
jQscript.src := ""

; Get Window object with proper permissions
window := ComObject(9,ComObjQuery(ie,IID,IID),1)

; Get jQuery body object
try body := window.eval("$('body')")
catch ; use execScript when eval (IE11+) fails
	body := window.execScript("$('body')")

; Call some jQuery
body.css("border", "4px solid red")