Although this is technically a blog, it's primary content is a series of articles on how to get Firefox working in a corporate Windows environment. Later ones build on earlier ones, so you might want to use the Table of Contents on the right to read through it chronologically instead of reading straight down from here.

Making Any Firefox Extension an MSI

Last updated September 2017

Now suppose you want to push out a particular extension to all your Firefox users.  You can build them into your Firefox MSI with FrontMotion's packaging service which is certainly convenient.  However, you can also roll it into its own independent MSI.  This has the benefit of being upgradable separately, and ultimately we're going to be altering an extension in a later article and this is going to be required to push it out.

Important: These instructions were written for legacy extensions, not the newer WebExtensions.  If you need older extensions to work you should use the Firefox 52 ESR releases, as they'll stop working in Firefox 57 and beyond.  The ESR release will be supported until May 2018.  When I make the switch off of that I'll update these instructions for WebExtensions.


Download and Extract

First, download your chosen extension as an XPI.  I'm going to be using Flashblock because there are no changes we need to make to it.  However, these instructions apply to any extension.

Go to the extension's page in addons.mozilla.org and right click on the Add to Firefox button.  Choose Save Link As and you'll get the raw XPI.

Now unpack the XPI to a folder.  XPIs are just ZIP files, so add .zip to the end of the file name and extract it.


Create the MSI

Now open install.rdf in a text editor.  You want to copy the contents of the <em:id> tag somewhere.  The first one, under the Description tag, not the one in the targetApplication group.  In this case Flashblock uses {3d7eb24f-2740-49df-8937-200b1cc08f8a}.

Now we need to download a nice piece of software called Advanced Installer to actually package this into an MSI.  They have a freeware edition, which is the same as the trial version except the Simple project type doesn't expire.  That's all we're going to need.

Fire it up, create a Simple project, and turn off the wizard.

In the Product Details section, change the Product Name, Version, and Company Name to whatever you want.

In the Install Parameters section, change Installation Type to "Per-machine only (fails if user is not administrator)".  We're going to need to access the HKEY_LOCAL_MACHINE part of the registry so this is required.  Since we're pushing it out via Active Directory it will always install under a privileged account anyway.

You don't need to check these, but I do anyway:
  • Limit to basic user interface.  Cuts out the nonsense if you ever have to install it manually, though you won't be able to install to anything other than the default location.
  • Don't save system restore points for installation.  Overkill for the changes we're making, and excluding it will make the install faster.
  • Perform only file costing and skip checking other costs.  Supposedly also makes the install faster.
Skip down to the Files and Folders section.  Right click on Application Folder and use Add Folder to add every subfolder of your unpacked XPI.   Then also use Add Files to include anything in the unpacked root folder.  It will look something like this when it's done:


Now go into the Registry section.  Go to HKEY_LOCAL_MACHINE/Software, right click and use New Key to create the hierarchy Mozilla/Firefox/Extensions one by one.  Then right click and choose New Value.

The name of the value will be the ID you copied from install.rdf.  In the case of Flashblock it's {3d7eb24f-2740-49df-8937-200b1cc08f8a}.  Choose String and Replace for the type, and put [APPDIR] for the value.  Do NOT include any quotes.  If you click Folder and choose the application folder that way it will add "[APPDIR] ".  I've found having the quotes around the path in the registry prevents Firefox from recognizing it.  It should look like this:


When you click OK it will show up on the right side in quotes.  That's okay.  If there were actual quotes in the value they would be doubled there.  Everything should now look like this:


Now head to the Media section.  Folder and File Name are just where you want the generated MSI to go.  Archive should be left on the defaults to make a self-contained MSI:


Now click Build to generate your MSI and you're done.

So what happens when it installs?  The MSI will create a folder on the hard drive with all the unpacked XPI files.  They'll be in Program Files\[Company Name]\[Product Name].  It will also add a registry key under Firefox/Extensions pointing to that path.  When Firefox sees that it will install the extension automatically.  Users won't be able to uninstall it as long as the registry key exists, though they will be able to disable it.

Some extensions like PlainOldFavorites don't work from C:\Program Files for whatever reason, they have to be in the user profile folder.  My login script can copy them over automatically if you add them to the copyExtensions variable.

Firefox is suspicious of extensions installed via the registry and may ask users if they really want them before enabling them.  This is great for consumers but bad for us.  Fortunately we can disable that feature.

Like the Flash MSIs it doesn't matter what order things are installed in.  If an extension is installed this way before Firefox it will be just fine.

2 comments:

  1. Under product details you might want to add the fact that you should include this if you are referencing a share not on the local computer.

    Product Details:
    Product Name: Extensions
    Company Name: Mozilla Firefox

    Install Parameters:
    Application Folder: [ProgramFilesFolder][Manufacturer]\[ProductName]

    If you don't do this your registry vaules will be wrong so will the location of your plugin.

    -Kevin

    ReplyDelete
  2. If you're referencing a share then there's no need to put the files in the MSI either. Doing so would make every client install try to overwrite the shared copy. At that point you'd essentially just be using a MSI to push out a registry key.

    ReplyDelete