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:

>> 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.

>> 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.

17 Comments

  1. jiyingjun
    8 years ago

    “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”
    hi,thanks for your wonderful post.I am a university student from China,and my english is not very good .hope you can understand. Recently i'm participating in a software competition, the subject requires a common browser plug-in, my idea is the same to you: combine plugin and activex controls together to make a dll, but I'm encountered with a great many difficulties, i use atl project to achieve activex,but win32 project for firefox's plugin,can you give me some guidance about how to combine the two different projects together?

  2. jiyingjun
    8 years ago

    thanks

  3. jiyingjun
    8 years ago

    “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”
    hi,thanks for your wonderful post.I am a university student from China,and my english is not very good .hope you can understand. Recently i'm participating in a software competition, the subject requires a common browser plug-in, my idea is the same to you: combine plugin and activex controls together to make a dll, but I'm encountered with a great many difficulties, i use atl project to achieve activex,but win32 project for firefox's plugin,can you give me some guidance about how to combine the two different projects together?

  4. jiyingjun
    8 years ago

    thanks

  5. taxilian
    8 years ago

    I'll put it on the list of requested topics; somehow, between full time college, full time work, and a 2 month old baby, I haven't had much time :-/

    Basically, though, the main thing to know is that the two aren't mutually exclusive; you can create an ActiveX control, and then you can add a firefox plugin into the same project simply by exporting the correct entrypoints from the same DLL in addition to the ones you are already exporting for the COM object. (see http://colonelpanic.net/2009/03/building-a-fire…)

  6. taxilian
    8 years ago

    I'll put it on the list of requested topics; somehow, between full time college, full time work, and a 2 month old baby, I haven't had much time :-/

    Basically, though, the main thing to know is that the two aren't mutually exclusive; you can create an ActiveX control, and then you can add a firefox plugin into the same project simply by exporting the correct entrypoints from the same DLL in addition to the ones you are already exporting for the COM object. (see http://colonelpanic.net/2009/03/building-a-fire…)

  7. taxilian
    8 years ago

    I’ll put it on the list of requested topics; somehow, between full time college, full time work, and a 2 month old baby, I haven’t had much time :-/

    Basically, though, the main thing to know is that the two aren’t mutually exclusive; you can create an ActiveX control, and then you can add a firefox plugin into the same project simply by exporting the correct entrypoints from the same DLL in addition to the ones you are already exporting for the COM object. (see http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/)

  8. taxilian
    8 years ago

    I'll put it on the list of requested topics; somehow, between full time college, full time work, and a 2 month old baby, I haven't had much time :-/

    Basically, though, the main thing to know is that the two aren't mutually exclusive; you can create an ActiveX control, and then you can add a firefox plugin into the same project simply by exporting the correct entrypoints from the same DLL in addition to the ones you are already exporting for the COM object. (see http://colonelpanic.net/2009/03/building-a-fire…)

  9. jiyingjun
    8 years ago

    haha,my idea is the same with you,i've been trying to do this for several days and succeed today,thanks for your reply,and now i'm trying to customize my own plug-in and adapter standards,and then achieve the corresponding adapter for different browsers.from your articles i find you have a thorough understanding of plugins,can you give me some guidences?thanks.谢谢 haha

  10. jiyingjun
    8 years ago

    haha,my idea is the same with you,i've been trying to do this for several days and succeed today,thanks for your reply,and now i'm trying to customize my own plug-in and adapter standards,and then achieve the corresponding adapter for different browsers.from your articles i find you have a thorough understanding of plugins,can you give me some guidences?thanks.谢谢 haha

  11. taxilian
    8 years ago

    I built a framework that had two different sides: the scriptable objects and application interface.

    The scriptable object side essentially consists of an NPObject on the firefox side and a COM object with no methods or properties defined in the IDL that implements IDispatchEx. I created a common “Scriptable API” class that can be wrapped by either the NPObject or the IDispatch object, and thus I'm able to define an API once and have it be completely cross platform.

    The application interface side isn't as well fleshed out, but basically I defined a common interface that I called, for lack of a better term, UIManager, and I have functions on that for setting the window, updating the window size/position, mouse and keyboard events, etc, and I handle those events and such in platform specific code and call the methods on the UIManager, which is platform agnostic. There are some challenges that way, but it seems the cleanest so far.

  12. jiyingjun
    8 years ago

    <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>
    <HTML>
    <HEAD>
    <META http-equiv=Content-Type content=”text/html; charset=gb2312″>
    </HEAD>

    <BODY>
    <div style=”margin:4px; padding:10px; font-size:14px; margin-bottom:10px;”><pre>阁下的来信已收到
    小生祝您天天快乐O(∩_∩)O
    ——季英军

    ——————————————–
    海量、安全、快速、专业!尽在126免费邮 http://www.126.com</pre></div>
    <div style=” margin:4px; padding:10px; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:12px; line-height:22px; border:1px dashed #ccc; background:url(http://mimg.163.com/xm/option/images/logo126_sm_mailletter.gif) #fffff7 no-repeat right bottom;”>
    <!–标题–>
    <div style=” font-weight:bold; color:#3675d6;”><img src=”http://mimg.163.com/xm/option/images/ico11x11_mailletter.gif” style=”margin-right:6px;” />生活小常识</div>
    <!–内容–>
    <div style=” color:#FF6600;”>毛衣洗涤时水温不要超过30度,用中性洗涤剂,过最后一遍水加少许醋,能防止毛衣缩水。</div>
    <!–来自–>
    <div style=” padding-top:6px; color:#777″>以上提示来自:网易126免费邮——你的专业电子邮局 http://www.126.com</div>
    </div>
    </body>
    </html>

  13. taxilian
    8 years ago

    I built a framework that had two different sides: the scriptable objects and application interface.

    The scriptable object side essentially consists of an NPObject on the firefox side and a COM object with no methods or properties defined in the IDL that implements IDispatchEx. I created a common “Scriptable API” class that can be wrapped by either the NPObject or the IDispatch object, and thus I'm able to define an API once and have it be completely cross platform.

    The application interface side isn't as well fleshed out, but basically I defined a common interface that I called, for lack of a better term, UIManager, and I have functions on that for setting the window, updating the window size/position, mouse and keyboard events, etc, and I handle those events and such in platform specific code and call the methods on the UIManager, which is platform agnostic. There are some challenges that way, but it seems the cleanest so far.

  14. TTadmin
    8 years ago

    Take a look here: http://wtvz.net/detect_plugin/online-browser-plugin-detect.php

    hope this helps you

One Trackback

  1. […] time, in Detecting the version of an ActiveX IE Browser plugin part one, I discussed the ToString() method of an ActiveX object, and how it is called when an ActiveX […]

Post a Comment

Your email is never published or shared. Required fields are marked *