Cross-browser plugin detection

Starting with IE11, the navigator object supports plugins and mimeTypes properties. In addition, the window.ActiveXObject property is hidden from the DOM. (This means you can no longer use the property to detect IE11.)

Plug-in detection code can now be consistent between browsers and you don't need to provide special code for Internet Explorer. Some webpages might need to be updated to use consistent techniques and some plugins might need to update their installation routines so that the right information is available to the new properties. Here, you'll learn how to do this.

Detecting plugins effectively

These changes may affect the way your existing sites detect plugins in one of two ways:

  1. Plugins might not be detected, even though they're installed.

    If your site uses the window.ActiveXObject property to determine if a plugin is present, you'll need to update your code to use the new properties instead.

    var plugin = navigator.plugins["Contoso.Control"];
    if(plugin) {
        // Contoso control is installed and enabled
    } else {
      try {
        plugin = new ActiveXObject("Contoso");
      } catch(e) {
        // Contoso control is not installed or disabled
      }
    }
    

    Note  As this example shows, IE11 still supports the ActiveXObject object type and you can use it to instantiate ActiveX controls. It is, however, no longer supported as a property of the window object.

     

    If your webpage detects the plugin for other browsers, you might already use these properties. If so, make sure this detection happens before any other form of detection. Also, make sure you are detecting features and providing effective fallback.

  2. Plugins might not report information in the navigator properties.

    To support the new properties, plugins need to update the Registry when installed:

    1. Under HKLM\SOFTWARE\Microsoft\Internet Explorer\NavigatorPluginsList create a key using the name to be reported by the plugins property.
    2. Create subkeys for each custom MIME type supported by the plugin, using the MIME type value as the name of the subkey.
    3. For 64-bit environments, add the same Registry entries to HKLM\SOFTWARE\Wow6432\Microsoft\Internet Explorer\NavigatorPluginsList.
    4. Verify that unique MIME types are properly registered with the device loading the webpage, as well as the server hosting the webpage.

    For example, suppose the Contoso Control uses an "application/contoso" MIME type. In this case, you:

    • Add a "Contoso Control" key under HKLM\SOFTWARE\Microsoft\Internet Explorer\NavigatorPluginsList.

    • Create a string (REG_SZ) subkey named "application/contoso".

    • Copy the same keys to HKLM\SOFTWARE\Wow6432\Microsoft\Internet Explorer\NavigatorPluginsList (for 64-bit environments).

    In addition, plugins should expose version details using techniques appropriate for the language used to create the plugin (such as VERSIONINFO). These are used as properties of the plugin object returned by the plugins property:

Detecting plugin versions effectively

Many plugins are maintained over time and there's no guarantee that the user has installed the latest version. The following example shows one way to use the plugin.version property to handle this.

Silverlight.isInstalled = function (version) {
    if (version == undefined)
    {
        version = null;
    }

    var isVersionSupported = false;

    try
    {
        var tryOlderIE = false;

        // Detect installation on IE11 and non-IE browsers
        try 
        {
            var plugin = navigator.plugins["Silverlight Plug-In"];
            if (plugin)
            {
                // Plugin object exists - check for version argument
                if (version === null)
                {
                    // no string to parse - plugin is installed
                    isVersionSupported = true;
                }
                else
                {
                    // there is a string to parse - check if requested version is installed
                    var actualVerArray = actualVer.split(".");
                    while (actualVerArray.length > 3)
                    {
                        actualVerArray.pop();
                    }

                    while (actualVerArray.length < 4)
                    {
                        actualVerArray.push(0);
                    }

                    var reqVerArray = version.split(".");
                    while (reqVerArray.length > 4)
                    {
                        reqVerArray.pop();
                    }

                    var requiredVersionPart;
                    var actualVersionPart;
                    var index = 0;

                    do
                    {
                        requiredVersionPart = parseInt(reqVerArray[index]);
                        actualVersionPart = parseInt(actualVerArray[index]);
                        index++;
                    }
                    while (index < reqVerArray.length && requiredVersionPart === actualVersionPart);

                    if (requiredVersionPart <= actualVersionPart && !isNaN(requiredVersionPart))
                    {
                        isVersionSupported = true;
                    }
                }
            }
            else
            {
                // Plugin object does not exist - get ready to try the IE detection approach.
                tryOlderIE = true;
            }
        }
        catch (e)
        {
            // Exception was thrown while checking for plugin object and version - get ready to try the IE detection approach.
            tryOlderIE = true;
        }

        if (tryOlderIE)
        {
            // Detect installation on IE10 and earlier IE browsers via ActiveXObject
            var control = new ActiveXObject('AgControl.AgControl');
            if (version === null)
            {
                isVersionSupported = true;
            }
            else if (control.IsVersionSupported(version))
            {
                isVersionSupported = true;
            }
            control = null;
        }
    }
    catch (e)
    {
        isVersionSupported = false;
    }

    return isVersionSupported;
};

This example is taken from the debug version of the Silverlight.js library, a helper file that helps Web sites to create advanced Silverlight installation experiences.