A common problem with installations is user-editable files and registry keys. Configuration of this nature is a problem for every installer technology, but here are some guidelines to help developers overcome problems like users’ preferences being reset during repair.
Windows Installer is a data-driven installation technology. Installing a patch on a Windows Installer installation package, an .msi file, is just a repair operation with some new data transformed by the patch. When this occurs, any updated features, or features explicitly listed in the REINSTALL property, are reinstalled, along with their components and all their components’ resources. For registry values, there is no versioning like there is for files, so if a reinstalled component includes registry values they will be overwritten.
For registry values, only defaults should be written – if at all – to a location appropriate for the installation. If the installation must be elevated already, writing these values to HKEY_LOCAL_MACHINE is appropriate. For per-user installations, you might have a separate registry key for defaults from which the application only reads. For per-machine installations, an application – as already detailed in several guidelines for Windows applications – should only ever read from HKLM unless it is some type of administration application. If your per-machine application supports global configuration data, use the same approach as for per-user installations of storing defaults in one key and overrides in another. One suggestion in this case is to use a key under HKEY_LOCAL_MACHINESoftwarePolicies[Manufacturer] for defaults to be overridden as policy dictates – the location where .adm and .admx files for system policies will typically write – and HKEY_LOCAL_MACHINESoftware[Manufacturer] for defaults that should not be overwritten. The latter may not even be necessary if in code you specify defaults when reading registry values. You might install values in this location when configuring differences between installations or machines based on machine data at the time of installation.
For non-versioned configuration files, you should use custom actions that modify only sections of those files. Conflict resolution should be considered carefully, based on the importance of your update versus the users’ preferences. The machine.config file in the Microsoft .NET Framework is an example of a file – an XML configuration file, to be exact – that should be modified and never replaced. When the mobile extensions for ASP.NET first became available, their installation merely modified that file appropriately. It’s also advantageous in Windows Installer to keep such configuration changes data-driven, so that you can easily change key information in a patch transform without having to repackage an updated custom action binary, which can be difficult to manage with multiple active patches for a product. This is the behavior of the WiX custom actions and tables for XML files, and it’s recommended you use these community-supported custom actions and tables if appropriate for your application installation needs.
If you do write your own custom action to update configuration files based on installation options, make sure that you update the creation and modification timestamps for these files so that they are the same. If your custom action does not do that, the modification timestamp would be newer than the creation timestamp and Windows Installer would not update, by default, that non-versioned file. Hash checks on non-versioned merely help Windows Installer determine if the file in the patch needs to be installed, comparing the hash values of both the file on disk and in the installation package.
Following these installation guidelines for user-editable configuration can benefit both you and your users by reasonably maintaining their preferences while affording you the opportunity to update configuration when necessary.