ISWIX, LLC View Christopher Painter's profile on LinkedIn profile for Christopher Painter at Stack Overflow, Q&A for professional and enthusiast programmers

Saturday, September 11, 2010

In Defense of Merge Modules

Neil Sleightholm recently commented:
"Personally I never use merge modules unless I am forced to!"
It's an interesting perspective and I invite Neil to tell more ( as an aside, I'm always interested in guest bloggers on the Deployment Engineering team.  Diversity in Opinion is always a good thing ).  Until then, I wanted to give a few of my thoughts.   

Let's begin by reviewing Windows Installer Tao Rule # 43

Rule 43: Think carefully about Merge Module Patching

Merge modules provide a standard method for delivering Windows Installer components and setup logic just like any redistributable software. For all practical purposes any MSI package can consume a merge module and start using the functionality exposed by the merge module. However, the servicing story of such an MSI package has a huge flaw. Since the setup author who owns the MSI doesn’t own the merge module, they have no way to deliver fixes to issues that are found in the merge module, unless the merge module owner makes them available. On the other hand, the owner of the merge module has no way of delivering the fixes directly to the clients who installed the MSI built after consuming his/her merge module. The bottom-line of the story here is:

•Do not consume merge modules of vendors who do not promise to fix their merge modules promptly when bugs arrive

•Be prepared to handle the heat when bugs are found in your merge module causing issues for others’ products that have consumed your merge module and you get to put out the flame

Merge modules are great to use for distributing authoring and building of your setup. However, if you intend to redistribute an MSM externally, you should review the servicing implications. If you can tightly control the MSM consumers and identify the relevant products, then it’s possible to service them with a single MSP (multi-product targeting). Otherwise the recommendation is to provide your technology as an MSI that must be chained into the setup
Let's begin with a little history lesson. Microsoft used to use Concurrent / Nested Installs and Merge Modules as a deployment option for Microsoft SQL Server Desktop Engine. Then along came some really nasty security vulnerabilities that exposed a glaring problem in servicing these products that were embedded in other products. Network / Systems Administrators simply couldn't patch there production systems easily to eliminate these worms. Then Microsoft started telling developers to not use these technologies and instead use Micro-Packages to deliver them. After awhile, the message mutated into something along the lines of "merge modules are evil".   Then there was the little problem that MSI doesn't actually provide a decent bootstrapper / chainer to put all these packages together and the proliferation of packages has made Add/Remove Programs look like total chaos.  

Now let's go back and re-read Rule #43 with a little emphasis on the parts that I find interesting:

Rule 43: Think carefully about Merge Module Patching

Merge modules provide a standard method for delivering Windows Installer components and setup logic just like any redistributable software. For all practical purposes any MSI package can consume a merge module and start using the functionality exposed by the merge module. However, the servicing story of such an MSI package has a huge flaw. Since the setup author who owns the MSI doesn’t own the merge module, they have no way to deliver fixes to issues that are found in the merge module, unless the merge module owner makes them available. On the other hand, the owner of the merge module has no way of delivering the fixes directly to the clients who installed the MSI built after consuming his/her merge module. The bottom-line of the story here is:

Do not consume merge modules of vendors who do not promise to fix their merge modules promptly when bugs arrive

•Be prepared to handle the heat when bugs are found in your merge module causing issues for others’ products that have consumed your merge module and you get to put out the flame

Merge modules are great to use for distributing authoring and building of your setup. However, if you intend to redistribute an MSM externally, you should review the servicing implications. If you can tightly control the MSM consumers and identify the relevant products, then it’s possible to service them with a single MSP (multi-product targeting). Otherwise the recommendation is to provide your technology as an MSI that must be chained into the setup
OK, so what am I getting at?   Yes, it's true that when I put merge modules in my installs from third parties ( typically Microsoft .. how ironic )  that the quality of my installs go down.   And it's true that Microsoft doesn't promise to provide fixes and updates to these modules and in many instances they don't provide MicroPackages to redistribute either.    So what's my alternative?  Break the component rules and author my own components for another companies  resources?   Yup, this is an ugly problem that's never solved except by not taking dependencies on those components and moving to newer technologies that get more love from third party vendors.  Still, I'm writing the install not the application so I don't typically get to make that call.

However,  I am certain that using merge modules internally  to distribute setup development is a good thing.   Comparable and even better in some situations then using  WiX Fragments / Libraries /  Binary Libraries or InstallShield Developer Installation Manifests.

First, Merge Modules are STANDARD and can be consumed by installers ranging from InstallShield to WiX.   Try consuming an InstallShield DIM in WiX or a WiX Fragment in InstallShield. 

Second, merge modules are atomic collections of components and setup logic.  This is actually fairly similar to WiX Fragments which according to their own documentation are also atomic and immutable.  WiX Binary Libraries and MSI Merge Modules both aim to solve similar problems.

Sure, using Fragments can speed up your build and give you a bit more flexibility ( like including two components in a fragment but Referencing them into two different features ).    However, you can do the same thing with merge modules by creating multiple merge modules with module dependencies to describe component / feature relationships.  With a little bit of creativity, Merge Modules can even be used to encapsulate AppSearches, CustomActions, Dialogs and more.

Over the last five years I've developed an architecture where I use an InstallShield Basic MSI project to describe a feature tree and product configurations to describe which features to consume.  This serves as a fishbone that I then flesh out with dozens to hundreds of merge modules and create dozens of product installers with.   I use Major Upgrades as my servicing strategy and the result is I've never had any problems that were caused by the use of Merge Modules.

In summary, you don't have to have a monolithic InstallShield project for each of the installs you own.  You can split it out and reuse components and logic through merge modules and not increase the fragility of your install.   In fact, you can realize considerable savings by eliminating wasted effort and decreasing the frequency of bugs in your baseline.

Yes, I will admit it:   I use Merge Modules and I'm OK with that.   Still,  I will be working on Fragment support for IsWiX.

2 comments:

  1. I author merge modules for use internally only. My biggest complaint is with using InstallShield to author merge modules. If you have a multi-language MSI installation, using InstallShield to author the modules is next to useless. IS doesn't support creating standard multi-language merge modules (with multiple langage CABs embedded in the module). The first thing I tried was separating language-specific components into their own IS generated merge modules (IOW, a separate merge module source file for language A, language B, etc.). However, that only works if you're going to create separate MSI databases for each language (you can then use InstallShield's build options to only pull in language-specific data at build time). If you need to include the language-specific components in the same MSI database then you're pretty much screwed with InstallShield generated merge modules if any of the components target localized folders (such as a localized program menu) or have any other localized strings (service names, target directories, shortcuts, etc.). In my [very large] product MSI database, I've pretty much had to have any localized component included in the main IS source file rather than in IS generated merge modules.

    My other warning would be in using the Microsoft Visual Studio C++ Runtime merge modules. My product currently has a dependency on the VS 2005 SP1 run time and there are several known issues with these modules that MS has not fixed (Google "SxsUninstallCA" to find them). I've finally gotten rid of these modules by distributing the Win32 assemblies as private side-by-side assemblies in my application's program files location according to the instructions in the Visual Studio "redist.txt". When I was using the MS modules, I had to re-condition the "SxsUninstallCA" CA so it didn't run.

    ReplyDelete
  2. Yup, those are the ugly MS MSM's I talked about.

    To be honest I've only briefly dove into localization. My investigations lead me to believe that WiX and InstallShield are both lacking in terms of what the MSI SDK says should be possible.

    I'd love to be able to make multilanguage MSM's and then aggregate them up into a single multilanguage MSI.

    Even if you are using Fragments, WiX currently has no built-in way to do this. You'd have to build the different MSI's and then use a bunch of custom build automation to generate your transforms and stream them back into a signle MSI.

    ReplyDelete