Beginning with Windows Installer 3.0, bare .msp files can be double-clicked (invoked with the default verb) and will install correctly, assuming no other problems. Windows Installer will determine the updated features based on the changed components and will automatically reinstall those features. The effect is the same as specifying those features in the REINSTALL property, which is what you had to do previously for patches. This can be done for patches on previous versions of Windows Installer as well.

When we build patches we keep track of what components are updated and added, then calculate what features are updated based on which features own the updated or added components. We stuff that into a unique property using the patch ID, which is defined as the KB number, and append ".PatchFeatureList". This allows us to define a type 51 custom action that sets the REINSTALL property to the value of the unique property. We must only do this when the Version9X property is set, however, because under Windows Installer 3.0 multiple patches could be installed from the command line and with a simple type 51 custom action we may not pick up all the features that were updated. Fortunately Windows Installer 3.0 and higher does that for us.

To make sure that the features' and their components' states are updated correctly and included in costing, the type 51 custom action should be sequenced before the CostInitialize action. This means that calling certain standard actions again like the ProcessComponents action — which may cause problems when called a second time when updating assemblies in-place — is not necessary.

What's also required is that you ship a feature to always be installed locally, perhaps setting the Level column in the Feature table to 1 and even setting the Attributes column to 24 to enforce that the feature cannot be advertised or absent and make sure that the feature is neither a parent or child feature. Because this feature should be used only for servicing you might also consider hiding from the UI by setting the Display column in the Feature table to 0 or null. Any components that are strictly for servicing — such as components with registry keys because the ARPSYSTEMCOMPONENT property is set to 1 — should then be parented to this feature.

Now that a feature will already exist in the RTM it won't be added by the patches and setting the ADDLOCAL property is not required, which would be if you added a new, unique feature to every patch. Setting the ADDLOCAL property would be necessary before calling the ProcessComponents action so that the feature already appears installed, otherwise setting the feature in the REINSTALL property would have no effect.