<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.atalasoft.com/cs/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Rick Minerich's Development Wonderland : com</title><link>http://www.atalasoft.com/cs/blogs/rickm/archive/tags/com/default.aspx</link><description>Tags: com</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>VerCache Madness with .NET ActiveX Controls</title><link>http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx</link><pubDate>Tue, 13 Jul 2010 15:37:39 GMT</pubDate><guid isPermaLink="false">647108ca-f046-4d8d-9feb-a7fbd2049b37:20896</guid><dc:creator>RickM</dc:creator><slash:comments>2</slash:comments><comments>http://www.atalasoft.com/cs/blogs/rickm/comments/20896.aspx</comments><wfw:commentRss>http://www.atalasoft.com/cs/blogs/rickm/commentrss.aspx?PostID=20896</wfw:commentRss><wfw:comment>http://www.atalasoft.com/cs/blogs/rickm/rsscomments.aspx?PostID=20896</wfw:comment><description>&lt;p&gt;About a year ago I was working on building our DotTwain ActiveX control and wrote &lt;a href="http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx"&gt;two&lt;/a&gt; &lt;a href="http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx"&gt;articles&lt;/a&gt; on some useful tips that I discovered.&amp;#160; Since that time, I’ve seen a problem on a few customer computers where, after upgrading once, the control would never run.&amp;#160; Instead, it would just try to reinstall after every page load. &lt;/p&gt;  &lt;p&gt;After much frustration, it turned out that the problem is related to a little-known Internet Explorer registry entry called VerCache.&amp;#160; &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Ext\Settings\{GUID}] &amp;quot;VerCache&amp;quot;&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I figured this out after noticing that every machine exhibiting this problem had the same value for VerCache.&amp;#160; Once the VerCache was set to this value, uninstalling did nothing.&amp;#160; The repeated-reinstallation behavior happened with any new version installed which shared the control GUID.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What’s a VerCache?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Strangely enough, searching for &lt;em&gt;&lt;a href="http://www.google.com/#hl=en&amp;amp;source=hp&amp;amp;q=&amp;ldquo;VerCache&amp;rdquo;+ActiveX"&gt;“VerCache” ActiveX&lt;/a&gt;&lt;/em&gt; gives you little more than an &lt;a href="http://blogs.msdn.com/b/askie/archive/2009/05/22/why-doesn-t-my-activex-control-fail-to-update-in-internet-explorer.aspx"&gt;IE Team blog post&lt;/a&gt; and &lt;a href="http://social.answers.microsoft.com/Forums/en-US/InternetExplorer/thread/cc0e30bd-ca53-4158-b6c0-5988eccd47a5"&gt;one MSDN forums entry&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;At first, I was very excited when I found this IE team blog post.&amp;#160; It appeared that I had found my solution. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Here in the above mentioned screenshots they both are having same file date time stamps and that Causes the VerCache registry key to not get updated.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;To resolve this , ensure that at least one of these parameters - “Created” date time stamp, “Modified” date time stamp or the file size, on the updated control is different from the old version of the control and you should be GTG!&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Unfortunately, this information seems to be incorrect, or at least overly vague.&amp;#160; I observed the same bad VerCache value on different machines with different version of the control.&amp;#160; Each of these had different “created” and “modified” time stamps.&amp;#160; In fact, the CAB, the installer in the CAB, and the control assembly itself each had different “created” and “modified” time stamps for every single version.&amp;#160; I even tried updating the INF and setup launcher timestamps to no avail.&lt;/p&gt;  &lt;p&gt;The only thing which did not vary consistently was file size as we rebuild and repackage our control for each DotImage version we release.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Some of the things I tried or considered.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Early on, I discovered simply deleting the registry key after uninstalling fixed the issue temporarily and was under the impression that it was a single bad version of the control causing this.&amp;#160; So, I wrote a small cleaner utility to fix the issue.&amp;#160; However, as time wore on it was apparent that this issue occurred in a somewhat random fashion with all versions of the control.&lt;/p&gt;  &lt;p&gt;Another simple fix I thought about was updating the control GUID with each version.&amp;#160; However, this would require updating both our documentation and demos with every build.&amp;#160; Additionally, our customers would need to update their javascript with every upgrade.&amp;#160; This was unacceptable.&lt;/p&gt;  &lt;p&gt;The next thing I tried was to have the installer launch a custom console program on install which cleaned the registry value.&amp;#160; This worked great in XP.&amp;#160; However, in Windows 7 the console program, even as admin, did not have access to the registry values I wanted to delete.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Finally, a solution.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In the end the only solution I found worked consistently and met our needs was to put custom installer actions into the control itself.&amp;#160; When both installing and uninstalling the installer calls the control’s custom actions which removes any existing VerCache value for the control.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;First, I snagged a class I had made previously for cleaning guid-based registry entries:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4fcde709-6e98-4cb7-9762-8821089cdbb1" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;max-height:300px;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;white-space:nowrap;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;delegate&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;RegActionBreakOnTrue&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;RegistryKey&lt;/span&gt; basekey, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; key);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;EventArgs&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color:#2b91af;"&gt;EventArgs&lt;/span&gt; { &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; T eventData; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; EventArgs(T eventData) { &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.eventData = eventData; } &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; T EventData { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; eventData; } } } &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;RegGuidCleaner&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; _guid;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; RegGuidCleaner(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; guid)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        _guid = guid;&lt;/li&gt; &lt;li&gt;        Locations = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;[] {};&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;[] Locations { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;RegistryKey&lt;/span&gt; GetPathBase(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; path)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;RegistryKey&lt;/span&gt; baseKey;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (path.StartsWith(&lt;span style="color:#a31515;"&gt;@&amp;quot;HKEY_CURRENT_USER&amp;#92;&amp;quot;&lt;/span&gt;))&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            baseKey = &lt;span style="color:#2b91af;"&gt;Registry&lt;/span&gt;.CurrentUser;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (path.StartsWith(&lt;span style="color:#a31515;"&gt;@&amp;quot;HKEY_LOCAL_MACHINE&amp;#92;&amp;quot;&lt;/span&gt;))&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            baseKey = &lt;span style="color:#2b91af;"&gt;Registry&lt;/span&gt;.LocalMachine;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ApplicationException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Unexpected location type: &amp;quot;&lt;/span&gt; + path);&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; baseKey;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; GetBaselessPath(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; location)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; truncatedLoc = location.Substring(location.IndexOf(&lt;span style="color:#a31515;"&gt;&amp;#39;&amp;#92;&amp;#92;&amp;#39;&lt;/span&gt;) + 1);&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; truncatedLoc;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; PerformRegActionForEach(&lt;span style="color:#2b91af;"&gt;RegActionBreakOnTrue&lt;/span&gt; action)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; location &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; Locations)&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; fullPath = location + _guid;&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af;"&gt;RegistryKey&lt;/span&gt; baseKey = GetPathBase(fullPath);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; baselessPath = GetBaselessPath(fullPath);&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (action(baseKey, baselessPath))&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff;"&gt;break&lt;/span&gt;;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        }&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; EnteriesExist&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; doesKeyExist = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            PerformRegActionForEach((baseKey, subkey) =&amp;gt;&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; key = baseKey.OpenSubKey(subkey);&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (key != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                {&lt;/li&gt; &lt;li&gt;                    doesKeyExist = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;                }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/li&gt; &lt;li&gt;                    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            });&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; doesKeyExist;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        }&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DeleteEntries()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        PerformRegActionForEach((baseKey, subkey) =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            {&lt;/li&gt; &lt;li&gt;                Messages(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;EventArgs&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;&amp;gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Deleting Registry Key: &amp;quot;&lt;/span&gt; + baseKey.ToString() + &lt;span style="color:#a31515;"&gt;@&amp;quot;&amp;#92;&amp;quot;&lt;/span&gt; + subkey));&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                baseKey.DeleteSubKeyTree(subkey);&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt; ex) &lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                Messages(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;EventArgs&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;&amp;gt;(ex.ToString()));&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        });&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;EventHandler&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;EventArgs&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;&amp;gt;&amp;gt; Messages = &lt;span style="color:#0000ff;"&gt;delegate&lt;/span&gt; { };&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;Please forgive the catch (Exception ex).&amp;#160; So far it has been unnecessary to handle failure cases for anything other than logging.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Next, I added a custom installer class to remove the entries: &lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:25bc1176-eb8d-4735-84b6-81686d4a70df" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;max-height:300px;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;white-space:nowrap;"&gt; &lt;li&gt;[&lt;span style="color:#2b91af;"&gt;RunInstaller&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;)]&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;partial&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;RegistryCleanerInstallerClass&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;Installer&lt;/span&gt;&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; RegistryCleanerInstallerClass()&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        InitializeComponent();&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; CleanVerCache()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af;"&gt;RegGuidCleaner&lt;/span&gt; cleaner = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;RegGuidCleaner&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;{&amp;quot;&lt;/span&gt; + &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;AcquisitionControl&lt;/span&gt;).GUID + &lt;span style="color:#a31515;"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            cleaner.Locations = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;[] { &lt;/li&gt; &lt;li&gt;                &lt;span style="color:#a31515;"&gt;@&amp;quot;HKEY_CURRENT_USER&amp;#92;Software&amp;#92;Microsoft&amp;#92;Windows&amp;#92;CurrentVersion&amp;#92;Ext&amp;#92;Settings&amp;#92;&amp;quot;&lt;/span&gt;, &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;             };&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            cleaner.DeleteEntries();&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; { }&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    [System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityPermission&lt;/span&gt;(System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityAction&lt;/span&gt;.Demand)]&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Install(&lt;span style="color:#2b91af;"&gt;IDictionary&lt;/span&gt; stateSaver)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.Install(stateSaver);&lt;/li&gt; &lt;li&gt;        CleanVerCache();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    [System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityPermission&lt;/span&gt;(System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityAction&lt;/span&gt;.Demand)]&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Commit(&lt;span style="color:#2b91af;"&gt;IDictionary&lt;/span&gt; savedState)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.Commit(savedState);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    [System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityPermission&lt;/span&gt;(System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityAction&lt;/span&gt;.Demand)]&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Rollback(&lt;span style="color:#2b91af;"&gt;IDictionary&lt;/span&gt; savedState)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.Rollback(savedState);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        CleanVerCache();&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    [System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityPermission&lt;/span&gt;(System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityAction&lt;/span&gt;.Demand)]&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Uninstall(&lt;span style="color:#2b91af;"&gt;IDictionary&lt;/span&gt; savedState)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.Uninstall(savedState);&lt;/li&gt; &lt;li&gt;        CleanVerCache();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I also decided to move the com registration into a custom action as well.&amp;#160; The installer-based registration had been intermittently not working which caused us to hand test every release version of the control before sending it out. &lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:89c375a9-4a17-41f4-bfa6-46ee72dfea29" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:'Courier New', Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;max-height:300px;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;white-space:nowrap;"&gt; &lt;li&gt;[&lt;span style="color:#2b91af;"&gt;RunInstaller&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;)]&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;partial&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ComRegisterInstallerClass&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;Installer&lt;/span&gt;&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ComRegisterInstallerClass()&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        InitializeComponent();&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    [System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityPermission&lt;/span&gt;(System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityAction&lt;/span&gt;.Demand)]&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Install(&lt;span style="color:#2b91af;"&gt;IDictionary&lt;/span&gt; stateSaver)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.Install(stateSaver);&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#2b91af;"&gt;RegistrationServices&lt;/span&gt; regSrv = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; System.Runtime.InteropServices.&lt;span style="color:#2b91af;"&gt;RegistrationServices&lt;/span&gt;();&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!regSrv.RegisterAssembly(&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.GetType().Assembly, &lt;span style="color:#2b91af;"&gt;AssemblyRegistrationFlags&lt;/span&gt;.SetCodeBase))&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            {&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;InstallException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Failed to register componenet for COM interop&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            }&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        }&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    [System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityPermission&lt;/span&gt;(System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityAction&lt;/span&gt;.Demand)]&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Commit(&lt;span style="color:#2b91af;"&gt;IDictionary&lt;/span&gt; savedState)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.Commit(savedState);&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    [System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityPermission&lt;/span&gt;(System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityAction&lt;/span&gt;.Demand)]&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Rollback(&lt;span style="color:#2b91af;"&gt;IDictionary&lt;/span&gt; savedState)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.Rollback(savedState);&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#2b91af;"&gt;RegistrationServices&lt;/span&gt; regSrv = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; System.Runtime.InteropServices.&lt;span style="color:#2b91af;"&gt;RegistrationServices&lt;/span&gt;();&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!regSrv.UnregisterAssembly(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.GetType().Assembly))&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;InstallException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Failed to unregister componenet for COM interop&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        }&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        {&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    [System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityPermission&lt;/span&gt;(System.Security.Permissions.&lt;span style="color:#2b91af;"&gt;SecurityAction&lt;/span&gt;.Demand)]&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Uninstall(&lt;span style="color:#2b91af;"&gt;IDictionary&lt;/span&gt; savedState)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.Uninstall(savedState);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af;"&gt;RegistrationServices&lt;/span&gt; regSrv = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; System.Runtime.InteropServices.&lt;span style="color:#2b91af;"&gt;RegistrationServices&lt;/span&gt;();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!regSrv.UnregisterAssembly(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.GetType().Assembly))&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            {&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;InstallException&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Failed to unregister componenet for COM interop&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            }&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        }&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Finally, I added the the custom action calls to the installer.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.atalasoft.com/cs/blogs/rickm/customAction1_1431B5FB.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="customAction1" border="0" alt="customAction1" src="http://www.atalasoft.com/cs/blogs/rickm/customAction1_thumb_4F851BB9.png" width="408" height="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.atalasoft.com/cs/blogs/rickm/customAction2_27DE9F8F.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="customAction2" border="0" alt="customAction2" src="http://www.atalasoft.com/cs/blogs/rickm/customAction2_thumb_329BF6E4.png" width="408" height="204" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;This still won’t allow an existing broken control to upgrade.&amp;#160; However, after manually uninstalling the old control, the new one will install and work fine.&amp;#160; At least that’s what I’ve found in IE 8.0.7600.16385 Update 0 on Windows 7 Enterprise 64-bit.&amp;#160; ActiveX tends to be a bit of a moving target these days.&lt;/p&gt;  &lt;p&gt;Now, let’s hope I never need speak of this again.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx&amp;amp;;subject=VerCache+Madness+with+.NET+ActiveX+Controls" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx&amp;amp;;title=VerCache+Madness+with+.NET+ActiveX+Controls" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx&amp;amp;title=VerCache+Madness+with+.NET+ActiveX+Controls" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx&amp;amp;;title=VerCache+Madness+with+.NET+ActiveX+Controls" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx&amp;amp;;title=VerCache+Madness+with+.NET+ActiveX+Controls&amp;amp;;top=1" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2010/07/13/vercache-madness-with-net-activex-controls.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.atalasoft.com/cs/aggbug.aspx?PostID=20896" width="1" height="1"&gt;</description><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/.NET/default.aspx">.NET</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/activex/default.aspx">activex</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/activex+control/default.aspx">activex control</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/com/default.aspx">com</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/winforms/default.aspx">winforms</category></item><item><title>.NET 2.0+ ActiveX Controls Part 2 – Controlling Internet Explorer via IWebBrowser</title><link>http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx</link><pubDate>Tue, 14 Jul 2009 16:11:38 GMT</pubDate><guid isPermaLink="false">647108ca-f046-4d8d-9feb-a7fbd2049b37:18848</guid><dc:creator>RickM</dc:creator><slash:comments>2</slash:comments><comments>http://www.atalasoft.com/cs/blogs/rickm/comments/18848.aspx</comments><wfw:commentRss>http://www.atalasoft.com/cs/blogs/rickm/commentrss.aspx?PostID=18848</wfw:commentRss><wfw:comment>http://www.atalasoft.com/cs/blogs/rickm/rsscomments.aspx?PostID=18848</wfw:comment><description>&lt;p&gt;After spending much time evaluating different approaches, I’ve found a way to easily and reliably grab the URL of my hosting page from inside of a C# based ActiveX Control.&amp;#160; This process involves using dynamic COM invocation to obtain the IWebBrower interface via my ActiveX control’s implicit IOleObject interface.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Introduction&lt;/h3&gt;  &lt;p&gt;IWebBrowser is useful for many things beyond just getting the currently displayed URL.&amp;#160; In fact, &lt;b&gt;it can control almost every aspect of Internet Explorer&lt;/b&gt;.&amp;#160; It can be used to completely control browser navigation, redirecting the browser to different pages, refreshing or even going forward and back. &lt;/p&gt;  &lt;p&gt;Also, it would be possible to go about this via a statically generated interface to shdocvw.dll.&amp;#160; However, using a static interface has the distinct disadvantage of failing quite explosively if the dll is not available.&amp;#160; &lt;b&gt;Dynamic invocation is much safer.&lt;/b&gt;&amp;#160; If something goes wrong we will simply get back null values instead of what we expected.&lt;/p&gt;  &lt;p&gt;If you don’t have much ActiveX experience, there are three important pieces of information to know about before starting:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Everything in COM is referenced by GUID. &lt;/li&gt;    &lt;li&gt;All COM access is done through querying existing COM objects. &lt;/li&gt;    &lt;li&gt;With a little syntactic sugar, C# takes care of much of the pain involved. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Defining our COM Interfaces&lt;/h3&gt;  &lt;p&gt;First we need to define the COM reference Guids for our top level browser service and the Internet Explorer application. &lt;/p&gt;  &lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; Guid _topLevelBrowserGuid = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Guid(&amp;quot;&lt;span style="color:#8b0000;"&gt;4C96BE40-915C-11CF-99D3-00AA004AE837&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2: &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; Guid _webBrowserAppGuid = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Guid(&amp;quot;&lt;span style="color:#8b0000;"&gt;0002DF05-0000-0000-C000-000000000046&lt;/span&gt;&amp;quot;); 
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Secondly, we need to define the &lt;b&gt;IServiceProvider&lt;/b&gt; COM interface.&lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: [ComImport,
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2:  Guid(&amp;quot;&lt;span style="color:#8b0000;"&gt;6d5140c1-7436-11ce-8034-00aa006009fa&lt;/span&gt;&amp;quot;),
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  3:  InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  4: &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; IServiceProvider
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  5: {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  6:   &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; QueryService(
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  7:     &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; Guid guidService, 
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  8:     &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; Guid riid,
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  9:     [MarshalAs(UnmanagedType.Interface)] &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; ppvObject);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 10: }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Third, we need to define the &lt;b&gt;IWebBrowser&lt;/b&gt; COM interface.&amp;#160; &lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: [ComImport, 
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2:  TypeLibType((&lt;span style="color:#0000ff;"&gt;short&lt;/span&gt;)0x1050), 
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  3:  Guid(&amp;quot;&lt;span style="color:#8b0000;"&gt;EAB22AC1-30C1-11CF-A7EB-0000C05BAE0B&lt;/span&gt;&amp;quot;)]
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  4: &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; IWebBrowser
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  5: {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  6:   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(100)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  7:   &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; GoBack();
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  8:   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x65)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  9:   &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; GoForward();
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 10:   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x66)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 11:   &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; GoHome();
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 12:   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x67)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 13:   &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; GoSearch();
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 14:   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x68)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 15:   &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Navigate([In, MarshalAs(UnmanagedType.BStr)] &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; URL, [In, Optional, MarshalAs(UnmanagedType.Struct)] &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; Flags, [In, Optional, MarshalAs(UnmanagedType.Struct)] &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; TargetFrameName, [In, Optional, MarshalAs(UnmanagedType.Struct)] &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; PostData, [In, Optional, MarshalAs(UnmanagedType.Struct)] &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; Headers);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 16:   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(-550)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 17:   &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Refresh();
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 18:   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x69)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 19:   &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Refresh2([In, Optional, MarshalAs(UnmanagedType.Struct)] &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; Level);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 20:   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0x6a)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 21:   &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Stop();
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 22:   [DispId(200)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 23:   &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; Application { [&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;: MarshalAs(UnmanagedType.IDispatch)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(200)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 24:   [DispId(0xc9)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 25:   &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; Parent { [&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;: MarshalAs(UnmanagedType.IDispatch)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xc9)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 26:   [DispId(0xca)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 27:   &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; Container { [&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;: MarshalAs(UnmanagedType.IDispatch)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xca)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 28:   [DispId(0xcb)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 29:   &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; Document { [&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;: MarshalAs(UnmanagedType.IDispatch)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xcb)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 30:   [DispId(0xcc)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 31:   &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; TopLevelContainer { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xcc)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 32:   [DispId(0xcd)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 33:   &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Type { [&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xcd)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 34:   [DispId(0xce)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 35:   &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Left { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xce)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; [param: In] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xce)] &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 36:   [DispId(0xcf)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 37:   &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Top { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xcf)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; [param: In] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xcf)] &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 38:   [DispId(0xd0)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 39:   &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Width { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xd0)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; [param: In] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xd0)] &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 40:   [DispId(0xd1)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 41:   &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Height { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xd1)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; [param: In] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xd1)] &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 42:   [DispId(210)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 43:   &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; LocationName { [&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(210)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 44:   [DispId(0xd3)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 45:   &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; LocationURL { [&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xd3)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 46:   [DispId(0xd4)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 47:   &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; Busy { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0xd4)] &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 48: }&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;It’s quite a large and so I won’t go into the details of each member.&amp;#160; You can find out more by reading the IWebBrowser2 &lt;a href="http://msdn.microsoft.com/en-us/library/aa752127%28VS.85%29.aspx"&gt;MSDN article&lt;/a&gt;.&amp;#160; It’s an extension of the IWebBrowser interface which means the overlapping members will have the same effect. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Using our COM Interfaces&lt;/h3&gt;

&lt;p&gt;Now that we have all of the necessary infrastructure in place, we must build a set of COM queries in order to obtain our &lt;b&gt;IWebBrowser&lt;/b&gt; instance.&amp;#160; The first step is getting our ActiveX control’s &lt;b&gt;IOleObject&lt;/b&gt; interface.&lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: Type type = control.GetType();
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2: Type iOleObjectType = type.GetInterface(&amp;quot;&lt;span style="color:#8b0000;"&gt;IOleObject&lt;/span&gt;&amp;quot;, &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;We then use the &lt;b&gt;iOleObjectType&lt;/b&gt; interface to retrieve the client site service provider from our ActiveX control. &lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (iOleObjectType != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2: {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  3:   oleClientSiteObj = iOleObjectType.InvokeMember(
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  4:     &amp;quot;&lt;span style="color:#8b0000;"&gt;GetClientSite&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  5:     BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  6:     &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;, control, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  7:   serviceProvider = oleClientSiteObj &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; IServiceProvider;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  8: }&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;By querying our COM Object’s client side service provider, we can obtain &lt;b&gt;shdocvw.dll’s&lt;/b&gt; COM interface via it’s GUID and the GUID of the interface.&lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (serviceProvider != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2: {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  3:   Guid topLevelBrowserGuid = _topLevelBrowserGuid;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  4:   Guid iServiceProviderGuid = &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(IServiceProvider).GUID;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  5:   serviceProvider.QueryService(
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  6:     &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; topLevelBrowserGuid,
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  7:     &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; iServiceProviderGuid,
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  8:     &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; topServiceProviderObj);
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  9:   topServiceProvider = topServiceProviderObj &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; IServiceProvider;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 10: }&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Finally, in a similar way, we can now obtain the &lt;b&gt;IWebBrowser&lt;/b&gt; interface from Internet Explorer’s COM interface via their GUIDs.&lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (topServiceProvider != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2: {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  3:   Guid webBrowserAppGuid = _webBrowserAppGuid;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  4:   Guid iWebBrowserGuid = &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(IWebBrowser).GUID;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  5:   topServiceProvider.QueryService(
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  6:     &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; webBrowserAppGuid,
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  7:     &lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; iWebBrowserGuid,
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  8:     &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; webServiceProviderObj);
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  9:   webBrowser = webServiceProviderObj &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; IWebBrowser;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 10: }&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Now, we have an instance the &lt;strong&gt;IWebBrowser&lt;/strong&gt; interface.&amp;#160;&amp;#160; For my purposes, I need only the URL currently displayed in the browser window.&lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (webBrowser != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2: {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  3:   url = webBrowser.LocationURL;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  4: }&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Using the &lt;strong&gt;IWebBrowser&lt;/strong&gt; allows you to access and control Internet Explorer in a way which is otherwise unavailable for .NET ActiveX Controls.&amp;#160; Thanks to .NET’s excellent COM interop capabilities it’s possible to do it easily in a safe and reliable way.&amp;#160; Also, this technique is known to work for IE 6 all the way through the newest versions of Internet Explorer.&amp;#160; For future reference, at the time of this article the newest is IE8.0.6001.18702.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;References and Additional Information&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx"&gt;Part 1 in this Series: .NET 2.0 ActiveX Control Gotchas (Safe for Scripting and Hooking into Events)&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa741313%28VS.85%29.aspx"&gt;MSDN: About the Browser&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://support.microsoft.com/kb/257717"&gt;How To Retrieve the Top-Level IWebBrowser2 Interface from an ActiveX Control&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://stackoverflow.com/questions/72048/net-activex-component-in-ie-how-to-get-browser-reference"&gt;StackOverflow: .NET ActiveX Component in IE&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://www.pinvoke.net/default.aspx/Interfaces/IWebBrowser2.html"&gt;PInvoke.NET IWebBrowser2 (Interfaces)&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx&amp;amp;;subject=.NET+2.0%2b+ActiveX+Controls+Part+2+%e2%80%93+Controlling+Internet+Explorer+via+IWebBrowser" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx&amp;amp;;title=.NET+2.0%2b+ActiveX+Controls+Part+2+%e2%80%93+Controlling+Internet+Explorer+via+IWebBrowser" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx&amp;amp;title=.NET+2.0%2b+ActiveX+Controls+Part+2+%e2%80%93+Controlling+Internet+Explorer+via+IWebBrowser" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx&amp;amp;;title=.NET+2.0%2b+ActiveX+Controls+Part+2+%e2%80%93+Controlling+Internet+Explorer+via+IWebBrowser" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx&amp;amp;;title=.NET+2.0%2b+ActiveX+Controls+Part+2+%e2%80%93+Controlling+Internet+Explorer+via+IWebBrowser&amp;amp;;top=1" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/07/14/net-2-0-activex-controls-part-2-controlling-internet-explorer-via-iwebbrowser.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.atalasoft.com/cs/aggbug.aspx?PostID=18848" width="1" height="1"&gt;</description><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/pinvoke/default.aspx">pinvoke</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/activex/default.aspx">activex</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/activex+control/default.aspx">activex control</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/com/default.aspx">com</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/IWebBrowser2/default.aspx">IWebBrowser2</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/iOleObjectType/default.aspx">iOleObjectType</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/IWebBrowser/default.aspx">IWebBrowser</category></item><item><title>.NET 2.0 ActiveX Control Gotchas (Safe for Scripting and Hooking into Events)</title><link>http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx</link><pubDate>Wed, 03 Jun 2009 17:41:00 GMT</pubDate><guid isPermaLink="false">647108ca-f046-4d8d-9feb-a7fbd2049b37:18569</guid><dc:creator>RickM</dc:creator><slash:comments>6</slash:comments><comments>http://www.atalasoft.com/cs/blogs/rickm/comments/18569.aspx</comments><wfw:commentRss>http://www.atalasoft.com/cs/blogs/rickm/commentrss.aspx?PostID=18569</wfw:commentRss><wfw:comment>http://www.atalasoft.com/cs/blogs/rickm/rsscomments.aspx?PostID=18569</wfw:comment><description>&lt;p&gt;&lt;a href="http://www.atalasoft.com/cs/blogs/rickm/image_734E1359.png"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I’ve recently been building an ActiveX Control in .NET 2.0 and thought I would share some of the problems I’ve run into, as well as their solutions.&amp;#160; I hope that in reading this you can avoid a few of the timesinks I fell into.&amp;#160; &lt;/p&gt;  &lt;h2&gt;&amp;#160;&lt;/h2&gt;  &lt;h2&gt;&lt;font size="4"&gt;Safe for Scripting&lt;/font&gt;&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://www.atalasoft.com/cs/blogs/rickm/image_1B82DD1D.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://www.atalasoft.com/cs/blogs/rickm/image_thumb_76851CA3.png" width="478" height="59" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;By default, ActiveX controls are not marked as safe for scripting.&amp;#160; This means that Internet Explorer will refuse to run a control given it’s default settings, even for sites in it’s Trusted security zone.&amp;#160; Thankfully, this is an easy problem to correct.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;&lt;font size="3"&gt;The Wrong Way&lt;/font&gt;&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://www.atalasoft.com/cs/blogs/rickm/image_26AEF818.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://www.atalasoft.com/cs/blogs/rickm/image_thumb_0CDAC1E9.png" width="404" height="75" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;It’s possible to hide this issue on the client machine by setting “Initialize and script ActiveX controls not marked safe for scripting.” to true or prompt.&amp;#160; This, of course, is not an acceptable solution as it will require all clients to do the same and in so doing potentially open them to malicious controls.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h3&gt;&lt;font size="3"&gt;The Correct Solution&lt;/font&gt;&lt;/h3&gt;  &lt;p&gt;There are two ways to mark an ActiveX control as safe for scripting.&amp;#160; The first, and easiest in the context of .NET, is to &lt;a href="http://blog.devstone.com/aaron/archive/2007/06/12/2409.aspx"&gt;implement the IObjectSafety interface&lt;/a&gt;.&amp;#160; The only caveat to this method is that it requires that you can modify the ActiveX control’s source code.&amp;#160; &lt;/p&gt;  &lt;p&gt;The second, more complex option, is to use COM Component Categories Manager.&amp;#160; While not requiring source changes and recompilation, this method requires a rather large amount of registry editing.&amp;#160; As I did not take this approach, I won’t delve into it further.&amp;#160; Additional .NET implementation information is available in &lt;a href="http://www.codeproject.com/KB/COM/RobinComCat.aspx"&gt;this CodeProject article&lt;/a&gt;.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;IObjectSafety&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Implementation requires first importing the IObjectSafety interface.&amp;#160; This is a simply a matter of declaring a interface with the ComImport attribute. &lt;/p&gt;  &lt;p&gt;While in most cases it is extremely important to ensure the Guid tags on your interface declarations are unique, in this case it equally important not to change it.&amp;#160; This is because the GUID attribute here is that of the IObjectSafety interface.&amp;#160; To put it plainly, &lt;strong&gt;changing the Guid in the following example will cause it to not work&lt;/strong&gt;.&lt;/p&gt;  &lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: [Flags]
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2: &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;enum&lt;/span&gt; IObjectSafetyOpts : &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; &lt;span style="color:#008000;"&gt;//DWORD&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  3: {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  4:     &lt;span style="color:#008000;"&gt;// Object is safe for untrusted callers.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  5:     INTERFACESAFE_FOR_UNTRUSTED_CALLER  = 0x00000001,
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  6:     &lt;span style="color:#008000;"&gt;// Object is safe for untrusted data.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  7:     INTERFACESAFE_FOR_UNTRUSTED_DATA    = 0x00000002,
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  8:     &lt;span style="color:#008000;"&gt;// Object uses IDispatchEx.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  9:     INTERFACE_USES_DISPEX               = 0x00000004,
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 10:     &lt;span style="color:#008000;"&gt;// Object uses IInternetHostSecurityManager.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 11:     INTERFACE_USES_SECURITY_MANAGER     = 0x00000008
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 12: }
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 13: 
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 14: &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;enum&lt;/span&gt; IObjectSafetyRetVals : &lt;span style="color:#0000ff;"&gt;uint&lt;/span&gt; &lt;span style="color:#008000;"&gt;//HRESULT&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 15: {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 16:     &lt;span style="color:#008000;"&gt;//The object is safe for loading.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 17:     S_OK            = 0x0,
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 18:     &lt;span style="color:#008000;"&gt;//The riid parameter specifies an interface that is unknown to the object.&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 19:     E_NOINTERFACE   = 0x80000004
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 20: }
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 21: 
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 22: [ComImport()]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 23: &lt;span style="color:#008000;"&gt;//This GUID is that of IObjectSafety. Do not replace!&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 24: [Guid(&amp;quot;&lt;span style="color:#8b0000;"&gt;CB5BDC81-93C1-11CF-8F20-00805F2CD064&lt;/span&gt;&amp;quot;)] 
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 25: [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 26: &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; IObjectSafety
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 27: {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 28:     [PreserveSig()]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 29:     IObjectSafetyRetVals GetInterfaceSafetyOptions(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; Guid riid, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; IObjectSafetyOpts supportedOpts, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; IObjectSafetyOpts enabledOpts);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 30:     [PreserveSig()]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 31:     IObjectSafetyRetVals SetInterfaceSafetyOptions(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; Guid riid, IObjectSafetyOpts optsMask, IObjectSafetyOpts enabledOpts);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 32: }
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 33: &lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;You then need only implement this interface in your ActiveX control as follows.&lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: ...
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2: &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; partial &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ExampleControl : IObjectSafety
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  3: {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  4:     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IObjectSafetyRetVals GetInterfaceSafetyOptions(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; Guid riid, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; IObjectSafetyOpts supportedOpts, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; IObjectSafetyOpts enabledOpts)
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  5:     {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  6:         supportedOpts = IObjectSafetyOpts.INTERFACESAFE_FOR_UNTRUSTED_CALLER | IObjectSafetyOpts.INTERFACESAFE_FOR_UNTRUSTED_DATA;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  7:         enabledOpts = IObjectSafetyOpts.INTERFACESAFE_FOR_UNTRUSTED_CALLER | IObjectSafetyOpts.INTERFACESAFE_FOR_UNTRUSTED_DATA;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  8:         &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; IObjectSafetyRetVals.S_OK;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  9:     }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 10: 
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 11:     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IObjectSafetyRetVals SetInterfaceSafetyOptions(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; Guid riid, IObjectSafetyOpts optsMask, IObjectSafetyOpts enabledOpts)
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 12:     {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 13:         &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; IObjectSafetyRetVals.S_OK;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 14:     }
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 15:     ...
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 16: }
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 17: &lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;With the IObjectSafety interface implemented to return INTERFACESAFE_FOR_UNTRUSTED_CALLER and INTERFACESAFE_FOR_UNTRUSTED_DATA, your object is considered scripting safe for use by Internet Explorer.&amp;#160; Your control should no longer require any non-default ActiveX related settings to run.&lt;/p&gt;

&lt;p&gt;INTERFACE_USES_DISPEX and INTERFACE_USES_SECURITY_MANAGER are mainly used for scripting engines and can be safely ignored.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h2&gt;&lt;font size="4"&gt;Hooking into Events&lt;/font&gt;&lt;/h2&gt;

&lt;p&gt;Working on my current project, I spent a not insignificant amount of time working to make events fire correctly.&amp;#160; I started with a simple implementation, similar to what is discussed in &lt;a href="http://www.codeproject.com/KB/cs/CreateActiveXDotNet.aspx"&gt;this article&lt;/a&gt;. &lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: &amp;lt;object id=&amp;quot;&lt;span style="color:#8b0000;"&gt;ActiveXExample&lt;/span&gt;&amp;quot; &lt;span style="color:#0000ff;"&gt;name&lt;/span&gt;=&amp;quot;&lt;span style="color:#8b0000;"&gt;ActiveXExample&lt;/span&gt;&amp;quot; 
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2:   classid=&amp;quot;&lt;span style="color:#8b0000;"&gt;clsid:21192EDE-868C-4b94-9D20-B822C42EA9D2&lt;/span&gt;&amp;quot; 
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  3:   codebase=&amp;quot;&lt;span style="color:#8b0000;"&gt;ActiveX.cab#version=1,0,0,0&lt;/span&gt;&amp;quot; VIEWASTEXT&amp;gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  4: &amp;lt;/object&amp;gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: [Guid(&amp;quot;&lt;span style="color:#8b0000;"&gt;C07F993D-242D-4c1e-AF1B-B77CAE5FD088&lt;/span&gt;&amp;quot;)]
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2: [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  3: &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; IExposedComEvents
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  4: {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  5:     [DispIdAttribute(0x60020001)]
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  6:     &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ExampleEvent(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; text);
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  7: }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  8: 
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  9: [Guid(&amp;quot;&lt;span style="color:#8b0000;"&gt;21192EDE-868C-4b94-9D20-B822C42EA9D2&lt;/span&gt;&amp;quot;)]
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 10: [ClassInterface(ClassInterfaceType.None),
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 11:  ComSourceInterfaces(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(IExposedComEvents))]
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 12: [ComVisible(&lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;)]
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 13: &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; partial &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ActiveXExample
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 14: {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 15:     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; ExampleEventHandler ExampleEvent;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 16:     ...
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 17: }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt; 18: &lt;/pre&gt;&lt;/pre&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: &amp;lt;script language=&amp;quot;&lt;span style="color:#8b0000;"&gt;javascript&lt;/span&gt;&amp;quot;&amp;gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2: &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; ActiveXExample::ExampleEvent(text)
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  3:     &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt; {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  4:         elem = &lt;span style="color:#0000ff;"&gt;document&lt;/span&gt;.getElementById(&amp;quot;&lt;span style="color:#8b0000;"&gt;status&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  5:         elem.innerHTML = text;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  6:     } &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt;(exception) {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  7:         &lt;span style="color:#0000ff;"&gt;alert&lt;/span&gt;(&amp;quot;&lt;span style="color:#8b0000;"&gt;Exception Thrown in Event: &lt;/span&gt;&amp;quot; + exception);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  8:     }
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  9: &amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;However, I found that my javascript events were not being registered.&amp;#160; After some fiddling, I discovered that I was able to capture the event by instead using the “for-object event” script tag. &lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:480px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  1: &amp;lt;script &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt;=&amp;quot;&lt;span style="color:#8b0000;"&gt;ActiveXExample&lt;/span&gt;&amp;quot; event=&amp;quot;&lt;span style="color:#8b0000;"&gt;ExampleEvent(text)&lt;/span&gt;&amp;quot;&amp;gt;
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  2: &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt; {
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  3:     elem = &lt;span style="color:#0000ff;"&gt;document&lt;/span&gt;.getElementById(&amp;quot;&lt;span style="color:#8b0000;"&gt;status&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  4:     elem.innerHTML = text;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  5: } &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt;(exception) {
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  6:     &lt;span style="color:#0000ff;"&gt;alert&lt;/span&gt;(&amp;quot;&lt;span style="color:#8b0000;"&gt;Exception Thrown in Event: &lt;/span&gt;&amp;quot; + exception);
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  7: }
&lt;/pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  8: &amp;lt;/script&amp;gt;
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  9: &lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;I’m still not quite sure why the Object::Event syntax didn’t work, as it is shown often in ActiveX sample code.&amp;#160; Still, if you find you are having issues getting events to fire correctly, this alternate syntax may be worth trying.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;&lt;font size="4"&gt;Additional Resources &lt;/font&gt;&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa751977(VS.85).aspx"&gt;MSDN: Safe Initialization and Scripting for ActiveX Controls&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Eric Lippert's Fantastic Eight Part Series: Script and IE Security&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;a href="http://blogs.msdn.com/ericlippert/archive/2004/01/09/49114.aspx"&gt;One&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/ericlippert/archive/2004/01/13/58403.aspx"&gt;Two&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/ericlippert/archive/2004/01/14/58700.aspx"&gt;Three&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/ericlippert/archive/2004/01/15/59076.aspx"&gt;Four&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/ericlippert/archive/2004/01/20/60801.aspx"&gt;Five&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/ericlippert/archive/2004/01/21/61236.aspx"&gt;Six&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/ericlippert/archive/2004/01/22/61745.aspx"&gt;Seven&lt;/a&gt; and &lt;a href="https://beta.blogs.msdn.com/ericlippert/archive/2004/01/23/62302.aspx"&gt;Eight&lt;/a&gt;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx&amp;amp;;subject=.NET+2.0+ActiveX+Control+Gotchas+(Safe+for+Scripting+and+Hooking+into+Events)" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx&amp;amp;;title=.NET+2.0+ActiveX+Control+Gotchas+(Safe+for+Scripting+and+Hooking+into+Events)" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx&amp;amp;title=.NET+2.0+ActiveX+Control+Gotchas+(Safe+for+Scripting+and+Hooking+into+Events)" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx&amp;amp;;title=.NET+2.0+ActiveX+Control+Gotchas+(Safe+for+Scripting+and+Hooking+into+Events)" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx&amp;amp;;title=.NET+2.0+ActiveX+Control+Gotchas+(Safe+for+Scripting+and+Hooking+into+Events)&amp;amp;;top=1" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/rickm/archive/2009/06/03/net-2-0-activex-control-gotchas-safe-for-scripting-and-hooking-into-events.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.atalasoft.com/cs/aggbug.aspx?PostID=18569" width="1" height="1"&gt;</description><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/.NET/default.aspx">.NET</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/VB.NET/default.aspx">VB.NET</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/C_2B002B002F00_CLI/default.aspx">C++/CLI</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/internet+explorer/default.aspx">internet explorer</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/activex/default.aspx">activex</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/activex+control/default.aspx">activex control</category><category domain="http://www.atalasoft.com/cs/blogs/rickm/archive/tags/com/default.aspx">com</category></item></channel></rss>