Default Integrity Level and Automation
Over on StackOverflow, danimajo asked for help in an interesting scenario. Basically, he’s trying to drive Internet Explorer through automation, but finds that when he navigates to an Intranet site, the hidden browser instance appears and he can no longer control it. What’s going on?
Background on Protected Mode
Internet Explorer’s Protected Mode is a security sandbox that relies upon the integrity level system in Windows. A process may have only one integrity level (IL), so if you navigate an IE instance between a Internet (Protected Mode, LowIL) and Intranet (non-Protected Mode, MediumIL) site, Internet Explorer must handle the navigation in a new process. In IE7 on Vista, this was very visible—a new browser window would open automatically. In IE8, with the introduction of Loosely-Coupled IE (LCIE), we can handle this more subtly.
Background on Loosely-Coupled IE
In LCIE, IE always has at least two processes—the browser Frame Manager process (which always runs at MediumIL unless you start IE as admin) and one or more browser Tab Content processes, which run at:
- LowIL for Protected Mode sites
- MediumIL for Intranet/Trusted sites
- HighIL (if IE is started as Admin)
Because the Frame Manager process can “visually” host tabs of any integrity level, if the user navigates a page from a LowIL zone to a MediumIL zone, the Frame Manager process can silently swap out the current tab process with a tab process running at a different integrity level. This operation is called a “Virtual Tab switch.”
Losing Control
For compatibility with the most likely scenarios, Internet Explorer assumes that the default tab process will be a Low Integrity tab. Hence, when Internet Explorer is created by COM Automation, the tab process defaults to a Low Integrity tab. If the browser determines that the navigation requires a Medium Integrity Tab Content process, a virtual tab switch is performed. Now, here’s where things get interesting—because the script or code driving Internet Explorer via Automation has a reference to the now-irrelevant tab process, it loses control.
Regaining Control
Now, it’s possible for the caller to handle this situation, by trapping the NewProcess event and reacting accordingly. However, this requires a fair bit of code, and in some cases it might be desirable for an automation caller to simply evaluate its own needs (e.g. it is only configured to navigate to Intranet pages) and invoke an instance of Internet Explorer running at MediumIL to start with. In languages like C++ and C#, this is easy, just CoCreate an instance of CLSID_InternetExplorerMedium ("{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}"). When using this CLSID, the object will default to a MediumIL Tab Content process. How this works under the covers is pretty simple: the registry key HKEY_CLASSES_ROOT\CLSID\{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}\LocalServer32 contains a REG_EXPAND_SZ with the value "%ProgramFiles(x86)%\Internet Explorer\iexplore.exe" -startmediumtab
Unfortunately, as far as I can tell, there’s no way for scripting languages like VBScript or JavaScript running in CScript or WScript to pass a CLSID into CreateObject—it only accepts a ProgID. UPDATE: WndSks noted in the comments below that you can use the syntax Set IE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")
There’s no ProgID that maps to CLSID_InternetExplorerMedium, but you can trivially create one with a simple registry update.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\InternetExplorer.ApplicationMedium]
[HKEY_CLASSES_ROOT\InternetExplorer.ApplicationMedium\CLSID]
@="{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}"
After that, you can invoke a MediumIL instance of IE from script like so:
Set IE = CreateObject("InternetExplorer.ApplicationMedium")
' IE.Visible = false ' This is the default
IE.Navigate2 "https://intranetpage/"
So long as you navigate this instance only to pages that run outside of Protected Mode, your automation code will not lose its reference and the Internet Explorer window will remain invisible, unless you explicitly change the visible property.
-Eric
Comments
Anonymous
August 03, 2011
Will it work if you pass a clsid: moniker to GetObject()? msdn.microsoft.com/.../aa392394(v=vs.85).aspxAnonymous
August 03, 2011
@RichB: That doesn't appear to work. I'm far from an expert on scripting though.Anonymous
August 03, 2011
Set IE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}") IE.Visible = trueAnonymous
August 03, 2011
Thanks, @WndSks-- your syntax does indeed work on Win7.Anonymous
August 03, 2011
Thanks Eric! Your answer was awesome and really helpfull!Anonymous
July 02, 2012
Thanks a ton... I created a function to go out and re-capture the lost IE8 windows. It worked pretty good, but would always cause the window to appear once the tie was broken.Anonymous
August 07, 2012
I’m have a problem in UI. In application contact us anchor tag is there,if we click on contact us anchor tag it open outlook, but application is logging out. first we thought that it is IE7 problem, in IE7 if we enable Protected mode which is available in tools, it works fine. same IE7 is using one of my team member, in his system application works fine,if we enable or disable Protected mode, application works good. in another application,same operating system same Contact-us link works good, means no operating system problem. then what might be the problem for this. IE7 Version is using by all the team members, it works good for some members and for others to work good, they need to enable to protected mode. Can you please help me on this issue.Anonymous
February 19, 2013
I found this very useful to understand the inexplicable problem with my internet automation. I first used WndSks GetObject which worked, but then I noticed I could use Set IE=new InternetExplorerMedium from Microsoft Internet Controls (Feb 2013)Anonymous
October 23, 2013
Can someone please share the sample of how to trap the 'NewProcess' event?Anonymous
November 12, 2013
Thank you @EricLaw and @skSdnW! Sorted me right out!Anonymous
December 10, 2013
Eric, thanks for your description above. I've been fighting this issue for a while and haven't found a description of what's going on until now. However I've tried to implement the suggestions above and my code still fails. Note that I need to have IE.Visible=False. Can you tell me if there is some reason that setting that flag to False causes the solutions above to not be applicable? I've tried: Set IEbrowser = CreateObject("InternetExplorer.application") Set IEbrowser = New InternetExplorerMedium Set IEbrowser = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}") And all fail on me. Note that I'm not a developer so my skills are challenged. Thanks for any thoughts you have on this. [EricLaw]: What are you trying to accomplish overall? Are you using VBScript or something else? Of the three strings you mention, only the 3rd might potentially work from VBScript. I wouldn't expect setting Visible to have any effect, but it would be simple enough for you to try changing that and see if it makes any difference.Anonymous
February 18, 2014
This post saved me so much time, great stuff. Using Set IE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}") instead of SET IE = createobject( internetexplorer.application ) resovled my issues with IE8 vs IE7 on my company's intranet. This post also gave me a better understanding and insight into IE security.Anonymous
February 25, 2014
Eric, You are a champ!!!!!! The problem that was hampering my work for the last 2 weeks is simply got resolved by this post and with your suggestion of using sing Set IE = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")... Thanks a Lot Eric!!!!!!!!! :)Anonymous
March 17, 2014
I followed the link in the article regarding the NewProcess event. Since I already implement a DWebBrowserEvents2 to handle navigation errors and OnQuit event I added code to handle NewProcess. My intent was to swap out my IWebBrowser2 interface pointer with the one the event documentation claims will be passed into the event handler. What I have found is that I get three arguments. The first is a "byref BOOL" (value is VARIANT_FALSE) and the third is an I4 (value as expected is one). However even though the second argument is of type VT_DISPATCH, the value is NULL. [EricLaw] Which version of IE? What zone/integrity are you navigating from and what zone/integrity are you navigating to? Can you share your code-snippet?Anonymous
March 17, 2014
The comment has been removedAnonymous
March 19, 2014
The comment has been removedAnonymous
August 13, 2014
The comment has been removedAnonymous
January 26, 2015
Same thing for us, NewProcesss is null. We use IE9 (mode IE9, intranet page) and Windows7(32). Does exist a special configuration for IE that i forget ? the second solution (-startmediumtab) seems to not share "session cookies" between "Ie". So the new page is used without the "session cookie" getting/existing in the first "ie". We don't want to use it. Help, please.