Occasionally I need to embed HTML in my applications. If it is
just to display some simple layout with basic interactions, I
might use a component such as HtmlRenderer. In most cases
want to display real pages from the internet - in which case I'm
lumbered with the
I'm aware other embeddable browsers exist, but the idea of shipping additional multi-MB dependencies doesn't make sense unless an application makes heavy use of HTML interfaces
WebBrowser control annoys me in myriad ways, but it does
get the job done. One of the things that occasionally frustrates
me is that by default it is essentially an embedded version of
Internet Explorer 7 - or enabling Compatibility Mode in a modern
IE session. Not so good as more and more sites use HTML5 and
Rather fortunately however, Microsoft provide the ability to configure the emulation mode your application will use. It's not as simple as setting some properties on a control as it involves setting some registry values and other caveats, but it is still a reasonable process.
The table below (source) lists the currently supported
emulation versions at the time of writing. As you can see, it's
possible to emulate all "recent" versions of Internet Explorer
in one of two ways - either by forcing a standards mode, or
!DOCTYPE directives to control the mode. The
exception to this dual behaviour is version 7 which is as is.
According to the documentation the IE8 (8000) and IE9 (9000) modes will switch to IE10 (10000) mode if installed. The documentation doesn't mention if this is still the case regarding IE11 so I'm not sure on the behaviour in that regard.
|11001||Internet Explorer 11. Webpages are displayed in IE11 edge mode, regardless of the !DOCTYPE directive.|
|11000||IE11. Webpages containing standards-based !DOCTYPE directives are displayed in IE11 edge mode. Default value for IE11.|
|10001||Internet Explorer 10. Webpages are displayed in IE10 Standards mode, regardless of the !DOCTYPE directive.|
|10000||Internet Explorer 10. Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode. Default value for Internet Explorer 10.|
|9999||Windows Internet Explorer 9. Webpages are displayed in IE9 Standards mode, regardless of the !DOCTYPE directive.|
|9000||Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode. Default value for Internet Explorer 9.|
|8888||Webpages are displayed in IE8 Standards mode, regardless of the !DOCTYPE directive.|
|8000||Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode. Default value for Internet Explorer 8|
|7000||Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode. Default value for applications hosting the WebBrowser Control.|
Setting the emulation version is very straightforward - add a value to the registry in the below key containing the name of your executable file and a value from the table above.
Note: If you do this from an application you're debugging using Visual Studio and the Visual Studio Hosting Process option is enabled you'll find the executable name may not be what you expect. When enabled, a stub process with a slightly modified name is used instead. For example, if your application is named
calc.exe,you'll need to add the value
calc.vshost.exein order to set the emulated version for the correct process.
As it makes more sense to detect the version of IE installed on the user's computer and set the emulation version to match, first we need a way of detecting the IE version.
There are various ways of getting the installed IE version, but the sensible method is reading the value from the registry as everything else we are doing in this article involves the registry in some fashion.
Older versions of IE used the
Version value, while newer
svcVersion. In either case, this value contains
the version string.
We can use the following version to pull out the major digit.
- I'm returning an
intwith the major version component rather a
Versionclass. In this example, I don't need a full version to start with and it avoids crashes if the version string is invalid
- For the same reason, I'm explicitly catching (and ignoring)
UnauthorizedAccessExceptionexceptions which will be thrown if the user doesn't have permission to access those keys. Again, I don't really want the function crashing for those reasons.
You can always remove the
try block to have all exceptions
thrown instead of the access exceptions being ignored.
The functions to get and set the emulation version are using
HKEY_CURRENT_USERto make them per user rather than for the entire machine.
First we'll create an enumeration to handle the different versions described above so that we don't have to deal with magic numbers.
Next, a function to detect the current emulation version in use by our application, and another to quickly tell if an emulation version has previously been set.
And finally, we need to be able to set the emulation version. I've provided two functions for doing this, one which allows you to explicitly set a value, and another that uses the best matching value for the installed version of Internet Explorer.
As mentioned previously, I don't really want these functions
crashing for anticipated reasons, so these functions will also
catch and ignore
UnauthorizedAccessException exceptions. The
SetBrowserEmulationVersion function will return
true if a
value was updated.
If you just want "fire and forget" updating of the browser emulation version, you can use the following lines.
This will apply the best matching IE version if an emulation version isn't set. However, it means if the user updates their copy if IE to something newer, your application will potentially continue to use the older version. I shall leave that as an exercise for another day!
While experimenting with this code, I did hit a major caveat.
In the original application this code was written for, I was
applying the emulation version just before the first window
WebBrowser control was loaded, and this worked
However, setting the emulation version doesn't seem to work if
an instance of the
WebBrowser control has already been created
in your application. I tried various things such as recreating
WebBrowser control or reloading the
Form the control was
hosted on, but couldn't get the new instance to honour the
setting without an application restart.
The attached demonstration program has gone with the "restart after making a selection" hack - please don't do this in production applications!
The are a lot of different options you can apply to Internet
Explorer and the
WebBrowser control. These options allow you
to change behaviours, supported features and quite a few more.
This article has touched upon one of the more common
requirements, but there are a number of other options that are
worth looking at for advanced application scenarios.
An index of all available configuration options can be found on MSDN.
- 2014-06-28 - First published
- 2020-11-21 - Updated formatting
Like what you're reading? Perhaps you like to buy us a coffee?