NPAPI plugin installation on Windows

This post is about how to take the npruntime code sample that I have blogged about and install it as a chrome extension.

In this series of articles I have provided the code to build a simple NPAPI plugin.  The next steps are to register the plugin with Firefox and Google chrome so we can test the code.

Firefox install

To install a plugin on Firefox under windows you need to use the registry.  That is the most reliable method to install the plugin.

The registry keys used to install the plugin are located in the HKey Local Machine (HKLM) registry hive, so administrative permissions will be required to install the plugin.



The path should be the absolute path to the npruntime dll.

Google Chrome installation

Installation on chrome is almost as easy.  Google has added a few steps to package the NPAPI control as an extension.  This extension can either display the plugin publicly, which could expose the client browser to security threats, or you can make the plugin private which only allows your script to access the plugin.

To begin, we need to create a manifest file manifest.json in a sub-folder that is named for the extension.  For this sample, there is a sub-folder installersChrome.  Inside this sub-folder we have a folder named npruntime.  Inside this folder we place all the files needed for the chrome extension.

  • icon.png
  • manifest.json
  • npruntime.dll

The manifest.json file should look like this:

package the plugin

The first step of installing the chrome extension is to create the CRX package.  To do this you need to navigate to the Chrome://extensions page and select the developer mode by selecting the checkbox in the upper right hand corner.  Once you have enabled developer mode, select the pack extension button.

chrome pack extension

Select the folder where the we have the nanifest.json file.

chrome pack select folder

For this sample, navigate to the sub-folder npruntime inside installerschrome.

chrome pack ready

Now we package the control and create a crx package that we can use to deploy to chrome. The second parameter is a path to your private key file used to provide a certified package. For this sample, leave it blank



chrome pack response

chrome pack success

When we succeed with the packaging, we will have the npruntime.crx and npruntime.pem file. DO NOT lose the pem file! this is a key assigned by chrome that is a key assigned to the control.

Retrieving the Extension ID

Now that you have the packaged extension you need to retrieve the extension ID.  To do this, you open the Chrome://extensions page and in the developer section select the “Load unpacked extension…” button.  You will be prompted to select the control to load, so navigate to the installerschrome folder and select the npruntime folder to load it into chrome.

After you load the unpacked extension, you will see a screen similar to this.  Highlighted is the extension ID assigned to this control.

After you load the unpacked extension, you will see a screen similar to this. Highlighted is the extension ID assigned to this control.

Now that you have the extension ID, you can complete the registration of the packaged NPAPI control by adding a pair of registry keys to the windows registry.

And that should do it.  You should be able to view the chrome NPAPI extension in the test.html file provided with the sample.



Source code for this project is available on github: https://github.com/chrisDwarner/npruntimeSampleCode

16 thoughts on “NPAPI plugin installation on Windows


  1. Hey! This is my first visit to your blog! We are a team of volunteers and starting
    a new initiative in a community in the same niche.
    Your blog provided us useful information to work on. You have done
    a extraordinary job!


  2. Hey! thanks for the nice article. i have installed NPAPI plugin using this extension. is there a way to install plugin in chrome without using extension.

    i am interested in getting the DOM details using my NPAPI plugin in chrome browser could you please guide me on that..

    thanks ….


    • Currently you need to have the Chrome extension to install a NPAPI plugin as far as I am aware of.
      I am sure you have read this link , since you have already installed the plugin. To get access to the DOM requires a bit a knowledge of how NPAPI works.

      With the NPAPI plugin you have complete access to the page that contains the loaded plugin. .

      To get access to the DOM you need to call into the Plugin API. For instance:

      NPObject *pNpWin = NULL;
      NPError err = NPN_GetValue( npInstance, NPNVWindowNPObject, &pNpWin);
      if ( err != NPERR_NO_ERROR)
      {
      NPIdentifier id = NPN_GetStringIdentifier("Document");
      NPVariant variantValue;
      bool bRet = NPN_GetProperty( npInstance, pNpWin, id, &variantValue);
      if ( bRet )
      {
      NPObject *DocObject = variantValue.value.objectValue;
      }
      }

      That is a rough template of how you can get access to the DOM through your plugin. for more infomation you can look here:

      Feel free to ask if you have more questions.


      • thanks for reply ..

        i want to call javascript function console.debug(“hello from c++”); from NPAPI plugin. i have taken following code

        // The message we want to send.
        char* message = “Hello from C++”;

        // Get window object.
        NPObject* window = NULL;
        NPN_GetValue(npp_, NPNVWindowNPObject, &window);

        // Get console object.
        NPVariant consoleVar;
        NPIdentifier id = NPN_GetStringIdentifier(“console”);
        NPN_GetProperty(npp_, window, id, &consoleVar);
        NPObject* console = NPVARIANT_TO_OBJECT(consoleVar);

        // Get the debug object.
        id = NPN_GetStringIdentifier(“debug”);

        // Invoke the call with the message!
        NPVariant type;
        STRINGZ_TO_NPVARIANT(message, type);
        NPVariant args[] = { type };
        NPVariant voidResponse;
        NPN_Invoke(npp_, console, id, args,
        sizeof(args) / sizeof(args[0]),
        &voidResponse);

        // Cleanup all allocated objects, otherwise, reference count and
        // memory leaks will happen.
        NPN_ReleaseObject(window);
        NPN_ReleaseVariantValue(&consoleVar);
        NPN_ReleaseVariantValue(&voidResponse);

        from link “http://www.m0interactive.com/archives/2010/10/21/how_to_communicate_back_to_javascript_from_npapi_plugin/ ”

        i am have written this code inside “ScriptablePluginObject::Invoke” function but when i trying to call test.html is is getting crashed.

        please let me know “am i calling this code at right place” and “how can i test this code”.

        thanks…


        • Without looking at test.html, it’s hard to say what is going on. Verify that the web page is loading the plug in properly. This could be a cause of the crash.

          Also, when are you invoking the call from the plugin? The page should be fully loaded. If you try to invoke the plugin before the page is loaded, I would expect it to crash.

          If the control loads and it still crashes, then you might need to wrap the console.debug() in a JavaScript handler function and invoke the handler function from the plugin.


  3. this is my test.html:
    window.onload = function(){
    test = document.getElementById(“pluginObj”);
    alert(test.CallPlugin());
    alert(test.CallJava());

    this is my in NPAPI sample code
    bool ScriptablePluginObject::Invoke(NPObject* obj, NPIdentifier methodName,
    const NPVariant* args, uint32_t argCount,
    NPVariant* result)
    {
    if(function_name ==CallPlugin )
    {
    //TILL HERE IT IS WORKING FINE
    }
    else if(function_name == CallJava)
    {
    //here it is getting crashed, here i have written the code which i have mentioned above
    }
    else{}
    return true;
    }

    i have verified that the page is loading successfully.
    thanks for reply….:)


  4. Hi chrisw52,
    I followed almost exactly what you described but I couldn’t load it.
    Here is what I did.

    a) I downloaded all source code from npruntimeSampleCode in GitHub, configured as Unicode project, changed the version in RC to 10.0.0.1 and built “npruntime.dll”which was created under a directory (C:worknpruntimeinstallerschromenpruntime) so that the following files were in that directory:
    – icon.png
    – manifest.json (its contents are below)
    {
    “name”: “npruntime”,
    “description”: “npruntime for Chrome”,
    “version”: “10.0.0.1”,
    “manifest_version”: 2,
    “browser_action”:{
    “default_icon”:”icon.png”
    },
    “plugins”: [
    { “path”:”npruntime.dll”, “public” : true}
    ]
    }
    – npruntime.dll

    b) Launched Chrome, changed the URL to “chrome://extensions”, clicked “Pack extension….” Button, packaged the plugin (which generated CRX and PEM files) and retrieved the ID (I got “lkdiknnjbpofajkcihlajefcmdojphem” ID) by clicking “Load unpacked extension” button.

    c) Since the step in (b) already loaded the npruntime plugin and I wanted to test if Chrome would load the plugin, I removed “npruntime” from “chrome://extensions” page by clicking the trash icon, and closed Chrome.

    d) Added the registry keys:
    Windows Registry Editor Version 5.00

    [HKEY_LOCAL_MACHINESOFTWAREGoogleChromeExtensionslkdiknnjbpofajkcihlajefcmdojphem]
    “Path”=”C:worknpruntimeinstallerschromenpruntimenpruntime.dll”
    “Version”=”10.0.0.1”

    f) Launched Chrome again, but Chrome didn’t load it.

    As a result, when I opened test.html from Chrome, it complaint “No plug-in available to display this content”. So I wonder if there is any step I did wrong, or I misunderstood.


    • I got most of that information from Mozilla off their developer site https://developer.mozilla.org
      Other information on NPAPI was taken from various searches off the internet.

      Feel free to use my blog articles in your presentation, but please properly list my blog as a reference for your work.
      Good luck on your presentation!


  5. In the latest Firefox version (32.0.3 I believe) where do you place your plugin DLL before you create the registry keys? The registry keys are still what you outline – i.e. MozillaPlugins


    • You should place the plugin into a folder where you want to install it. At this point you would follow the normal procedures for installing a windows app or plugin. So if you want to grant access for all users, you would install the plugin into a folder in the “Program files (x86)” folder, or if you want only the current user to have access, install the plugin to their AppDataLocalLow or AppDataRoaming folder and then use the absolute path to the plugin location in the registry key MozillaPlugins.

  6. Pingback: NPAPI plugin installation on Windows | conedogers

Comments are closed.