MSI

From MozillaWiki
Jump to: navigation, search

Plan for the Windows Installer (MSI) packaging of Firefox and other toolkit apps.

Bugs

Current work is proceeding in Bug 231062. Dependent bugs exist to track features that are not going to be part of the initial patch.

Plan

The plan is to create a fully automated MSI production system based on the WiX toolset, using what tools we can from WiX and implementing our own when necessary. Specifically, we are using the WiX compiler and linker (candle and light respectively) to compile and generate packages from the XML input.

The WiX XML input is a combination of product branding information, shell integration, and custom actions specified in the tree and information about the files to include generated by pyheat.py. Pyheat is a python analog of the WiX heat tool that can process Mozilla's package-manifest and removed-files information to generate the proper XML. Rolling our own has the advantage of being customizable and allowing custom validation (heat, for instance, will simply grab whatever is in the directory, while pyheat will see that files listed in the package-manifest are missing and die)

Integrating with existing browser components

Shell Integration

Originally the idea was to split out the shell integration functions from the NSIS uninstaller into a separate executable. I am beginning to think that that may not be the best path though, because:

  • It requires rewriting a lot of NSIS script based code into C++, which is uglier, more verbose, and prone to error. Furthermore, we cannot remove much of the NSIS script because other toolkit apps rely on it.
  • Requires executing this executable as a custom action in the MSI, which means that a lot of normal MSI capabilities (such as repair, etc) will not apply to the shell integration data
  • The MSI format already provides native methods for registry data, etc which are easier (IMO) to deal with and certainly easier to maintain when compared to C++. The app can then use the MSI api to [|re|un]install the integration data.

Not really sure which direction this will go yet.

Updates

The plan for updates is to reuse as much of the existing infrastructure as possible. We will add a new command, "msiexec" to the update manifest shipped in Mozilla's update system already. This command will tell the updater to use the MSI api to install the bundled MSI or MSP (patch). We will reuse the MAR format and the existing updater to do this. We will write the ProductCode to an ini file on installation so that the updater can be sure that it's patching the right instance of the application (so that in the future side by side installation can be supported).

Patches will be created by using the WiX tools (torch and pyro) and some branding information. An MSI patch is very similar to the partial MARs we currently generate and ship for updates. Creating a patch requires only the two relevant MSI files. We will create patches only for updates between point releases. (3.6.n -> 3.6.n+1) For updates from one branch to another (3.6 -> 4.0) we will ship the entire MSI inside the MAR.

L10n

The current Win32 installer is "repacked" for l10n purposes. That is, it's built once with the en-US locale and then the installer is uncompressed, the appropriate files replaced for the ab-CD locale, and recompressed to produce localized installers.

The MSI format does not admit this same approach easily because the metadata must be updated as well. The potential approaches are:

  • Use MST files (transforms) to transform the en-US MSI into an ab-CD MSI. This would require generating a transform, which WiX seems to provide no way to do that does not involve already having the ab-CD MSI in hand.  There are ways to create the MST with VBScript automation and other stuff, but I'm not terribly keen on that.  This also has the disadvantage of shipping both the en-US and ab-CD locale files with every localized installer (I am not aware of any way to remove files through an MST)
  • Package the nonlocalized components of the build into a wixlib (essentially a giant object file) and then build each locale separately from the wixlib. This requires some work on releng's part to pull out the wixlib and then build all the other locales on top of it, though probably not significantly more than repackaging already takes.

I definitely prefer the second option.