Mailbag: How to retain user-customized files during a Windows Installer major upgrade


Question:

I have an application that installs some .config files that users can customize.  I want to implement a Windows Installer major upgrade to install new versions of my application on systems that have an older version installed.  During the upgrade, I want to keep any customizations that users have made to the .config files instead of replacing them with new versions of the files.

How do I configure a major upgrade so that customized .config files will not be replaced during the upgrade process?

Answer:

The first thing to keep in mind is that a Windows Installer major upgrade is simply an install operation and an uninstall operation combined into a single installation session.  Whether or not .config files get replaced depends on how you author the information in your MSI.

There are a couple of key things you need to do to enable this behavior:

1.  Place each .config file in its own component and mark the .config file as the key path of the component.

Doing this will ensure that Windows Installer will use unversioned file replacement logic when deciding whether or not to replace this file in the install of your new version.  The high-level summary is that Windows Installer will compare the creation time of the component's key path file with the last modified time if both the old and new versions of the file are unversioned.  If they differ, then Windows Installer assumes the user has modified it and it will not replace it.

2.  Schedule the RemoveExistingProducts action in the new version of your MSI after the InstallFiles action.

Doing this will make sure that the new versions of all of your components are installed before removing the old version of your MSI.  When the new versions are installed in this sequence, your components will have their reference counts incremented to 2, but the .config files will not be replaced unless they are unmodified (because of the unversioned file replacement logic described in item 1 above).  Then, when the old version of your MSI is uninstalled afterwards during the RemoveExistingProducts action, the reference counts will be decremented back to 1, but the files will not be removed the system because the reference counts are not yet 0.

If you schedule RemoveExistingProducts before InstallFiles, then the uninstall of your old version will cause the component reference counts to reach 0, and the files will be removed from disk.  When the new versions of your components are installed afterwards, the files will be replaced with the new versions.  This will cause your users to lose any customizations they have made to their .config files.

The .NET Framework 2.0 SP1 and SP2 are implemented as major upgrades of the original version of the .NET Framework 2.0.  It has the same requirement of keeping any customizations the user has made to .config files.  The .NET Framework 2.0 SP1 and SP2 installer schedules RemoveExistingProducts in the following specific order because otherwise, it would encounter an ICE63 warning:

Comments (4)

  1. ran.davidovitz@gmail.com says:

    Aaron, thank you for a great to the point post (its amazing that just now i asked the use case you described)

    One thing that i don’t understand is how to handle configuration files that i allow my customer to update, e.g.

    1. deploy the file and cant update it later

    2. Take the approach of custom action that actually build the XML (update the xml file e.g. using XMLCONFIG in WiX)

    3. Both?

    In general i would like to deploy a default configuration file and allow customer to override its values on a new file (which is not my components) – but i don’t know of any implementation that allows me to do so currently (webform, winform), do you ?

    In Wix the section of XMLCONFIG is poorly documented (i decided to contribute and describe it better :)). also converting current XML file that i have to a set of XMLCONFIG element is hard

    Do you have any new practice for the entire issue?

  2. albert@insad.nl says:

    Hi,

    Another solution, which I use, is to read the .config file from the system before removing or installing the update/upgrade.

    After this you can uninstall the existing components and during installation of the new components you can create the new .config with the preloaded (before removing) values.

    This is usefull when you have extended the config file with new elements.

    At this moment we use WiX 2 for stability and to make this all work well we did need a CA for this but I recon in WiX 3 this is no longer required 😉

  3. Hi Ran Davidovitz – I’m not sure I understand your question.  The information in this blog post will allow you to configure your installer so that user customizations to config files will not be ignored/deleted.  The .NET Framework setup has a scenario that you describe – it deploys default config files and allows customer to override its values afterwards.  Are you looking for some kind of UI to allow users to graphically edit a config file?  Could you please clarify your scenario further so I can understand better?

    Hi ALbert van Peppen – Your stragety should work, but if you are reading/writing config files on the fly during your install process, you will need to use a custom action, even in WiX v3.0.  There is a built-in XmlConfig custom action that you can use so you should not have to write your own custom action code to accomplish this though.

  4. Armin says:

    Albert, can you give me the details of how you did this?

    I tried in a CA to rename an existing folder of my previous installation before it get's deleted in the RemoveExistingProducts action. When I schedule it to 'After InstallValidate' (just before RemoveExistingProducts), then I get some Transaction record error. When I schedule it later (e.g. 'After StopServices', several steps before RemoveFolders), then the sub folder I want to preserve had already been deleted by the uninstall.

Skip to main content