Detecting the version of an ActiveX IE Browser plugin

January 6, 2009 18 Comments by Richard

Update: if you haven’t already, please read up on FireBreath, the open source cross-platform plugin framework, and consider contributing.

Blog site up

Well, ColonelPanic.net is up and running, and I guess that means it’s time to start posting!  The primary intent of this blog is to provide a place to post solutions to development and technical problems that we have been able to find only after a lot of research and testing on our own.  Google is a wonderfully useful tool for developers, but it doesn’t seem to do very well at producing information that hasn’t been written.  So, while we wait for the google engineers to correct this oversight, we decided we needed to take action to at least make sure that our hard-earned knowledge isn’t totally lost.

What got me started

So, as part of my gainful employment this week I have been working at improving our browser plugin install methods.  Move Networks has the most impressive online video player that I have ever come across (which is basically why I decided to work for them), but there are always things that can be improved with any system.  Recently my task has been to streamline our install process.

One of these days I will post details on how we have combined our (IE) ActiveX control with our (firefox) NPAPI plugin in the same DLL, but that will need to be the topic of a different post.

Finding a solution to a problem

One of the trickiest tasks with any browser plugin is to detect if the installed plugin is the version that you need.  This is made particularly difficult because there are multiple browsers and multiple browser types.  During my research I looked over the default installer that Microsoft ships with Silverlight and found a very simple solution to the Internet Explorer half of this problem.  Essentially, the packaged silverlight.js file instantiates the ActiveX control using javascript and then calls a method to verify the version:

control = new ActiveXObject('AgControl.AgControl');
if ( version == null )
{
    isVersionSupported = true;
}
else if ( control.IsVersionSupported(version) )
{
    isVersionSupported = true;
}
control = null;

In this example, version is passed into the function and indicates the lowest allowed version of Silverlight.  In our plugin, we want to do something similar — except in our case, we wanted to be able to just get the actual version.

How it works

So, the first question that we need to answer is: How does internet explorer know which ActiveX control we’re referring to withnew ActiveXObject(‘AgControl.AgControl‘);”?  Well, as it turns out, this can be configured in the system registry.  I found some documentation in the MSDN that covered several topics, including this one.  Essentially, there are two locations in the registry where an ActiveX control can be assigned to a “<Major>.<Minor>” name:

  1. [HKEY_CURRENT_USER\Software\Classes]
  2. [HKEY_LOCAL_MACHINE\Software\Classes]

If you want to register this for the whole system, then put it in HKEY_LOCAL_MACHINE.  Otherwise, put it in HKEY_CURRENT_USER, which can be written to without having administrator privileges.  The HKEY_CLASSES_ROOT key shows a combination of the two; a key that exists in both will be taken from HKEY_CURRENT_USERSee this explanation from the MSDN for more info.

Implementation problems

Armed with this understanding, I set out to make it work with our ActiveX plugin.  I set up the registry keys, opened Jash, my favorate javascript debugging tool, and tried creating my plugin:

&gt;&gt; control = new ActiveXObject("QSP2IE.QSP2IE")
Object doesn`t support this property or method

That’s not real helpful!  ActiveXObject patently does support creating instances of an activeX object; my plugin is, indeed, registered under that name!  Why isn’t it working?  Well, that took some debugging.  I ended up creating my own method for the GetIDsOfNames method of the IDispatch Interface that ActiveX uses to expose members to the browser.  As it turns out, creating an ActiveX Object instance in this way calls the ToString() method on the plugin.  Gah! I haven’t found this documented anywhere (if you find it, please post a link), but I added it to the IDL of my plugin anyway.

&gt;&gt; control = new ActiveXObject("QSP2IE.QSP2IE")
"071300000030"

Success! It works!  Since my implementation of the ToString() method simply returns the version string, Jash shows me the output when it first creates the object.

The one downside so far is that if you update the DLL file while IE is still open, calling new ActiveXObject() again doesn’t get the new plugin version. This might end up being a showstopper for me!  We’ll see how it turns out.