0

I'm using WiX 3.8 (the latest stable release, I think), and I can't seem to get a config file to not get uninstalled-and-reinstalled during a major upgrade.

There are lots of questions about this on SO -- a lot of answers point to this site as a good answer. However, the suggestion given doesn't work (for me).

What the site says is to place each config file in its own component and mark the file as the key path of the component. Something like this:

  <Component Id="config.xml"
             Guid="*"
             Directory="folder_where_config_file_lives">
         <File Id="config_file"
               Source="$(var.Project.ProjectDir)bin\Release\configFile.xml" 
               KeyPath="yes"/>
  </Component>

Great. Next it says to schedule RemoveExistingProduct after the InstallFiles action, like so:

<InstallExecuteSequence>
     <RemoveExistingProducts After="InstallFiles"/>
 </InstallExecuteSequence>

Problem is, when I compile, I get this error:

The InstallExecuteSequence table contains an action 'RemoveExistingProducts' that is declared in two different locations. Please remove one of the actions or set the Overridable='yes' attribute on one of their elements.

This person also had that problem, but he seems to have solved it. What fixed it for him was adding a scheduling attribute to the , which effectively got rid of the "two different locations" declaration problem (I guess):

        <MajorUpgrade  Schedule="afterInstallInitialize"
                       DowngradeErrorMessage="A newer version of [ProductName] is already installed."/>

So when I substitute the schedule change attribute (which contains a attribute itself, I guess), not only does it not work -- the config file gets removed and replaced during the upgrade -- it causes even more weirdness. My project has a bootstrapper with a lot of MSIs, and although I get log files for the installation of all of the MSIs that are after the MSI that contains the config file, they aren't installed.

Let me repeat that: the logs say that the MSIs are installed, but they aren't. There's probably a rollback somewhere that I can't find in the log files, but reading the MSI log files it looks like the installation went swimminly.

Does anyone know a way for a config file to not be removed-and-reinstalled during a Major Upgrade in Wix 3.8? What I've mentioned above is the best info from the interwebs that I could find, but I've tried pretty much everything on SO to no avail.

Bob
  • 369
  • 1
  • 4
  • 24

2 Answers2

2

The MajorUpgrade element has everything you need, including where the RemoveExistingProducts action is scheduled. Don't add a RemoveExistingProducts into a sequence as well.

RemoveExistingProducts shouldn't be after InstallFiles. It's not clear where that comes from, but the documentation doesn't say that's a choice:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa371197(v=vs.85).aspx

When RemoveExistingProducts is sequenced early (such as after InstallInitialize or InstallValidate) it means that you are effectively uninstalling the old product followed by an install of the new product upgrade, and that means uninstalling the config file and installing the one in the upgrade. The way to retain the config file is to schedule REP afterInstallExecute. This results in an upgrade that is basically a version-rules install of the new product over the older installed one. The version rules mean that if you want updated binaries you must update their file versions. The good news about data files (your config file) is that updated data files won't be replaced:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa370531(v=vs.85).aspx

The older product then gets uninstalled, retaining the resulting set of files.

So sequencing of REP afterInstallExecute in the MajorUpgrade seems to be what you want. A caveat is that you need to follow component rules, which should happen automatically if you have auto-generated * guids in WiX.

PhilDW
  • 20,260
  • 1
  • 18
  • 28
  • Hallelujah! Your suggestions works! These links that you gave... MSDN seem to assume that the reader understands a lot of the terminology. Is there a "Windows Installer for people who were dropped on their heads as a baby" textbook or something that you could recommend? I have ORCA, so I can look at the sequences, but I haven't found a place to learn this stuff from scratch (the Nick Ramirez textbook, as great as it is for a noob, doesn't cover it as deep as is needed to really develop). Where did you learn this? (Snarky answer cheerfully accepted.) – Bob Oct 16 '17 at 14:42
  • See if you can still get Definitive Guide to Windows Installer, old, but still relevant, covers the basics :). – PhilDW Oct 17 '17 at 00:32
  • I shall. Thank you. – Bob Oct 17 '17 at 12:07
  • Good book. I still remember getting hired at a place in 2005 and having a new teammate hand me the book and say "you may know InstallShield but you need to know MSI. Read this." I just laughed inside thinking "Ah, Phil Wilson, ya, we know each other." – Christopher Painter Oct 17 '17 at 12:20
  • @PhilDW I have that book on my desk; I knew your name was familiar :) – Brian Sutherland Oct 17 '17 at 18:51
0

IMO, Windows Installer was invented before XML caught on and the component rules don't handle it well. What I prefer to do is to not fight this behavior. Write your application so that one config file is owned by the installer and can always be safely overwritten and another config file that holds your user configuration data and that MSI doesn't know about. This second file should take override the first file.

Christopher Painter
  • 54,556
  • 6
  • 63
  • 100
  • thanks for the suggestion. PhilDW's answer seems to work, but it may not in the long run, and I may end up following your suggestion (I have often found myself just writing Custom Actions to solve problems that WiX supposedly has answers for because I couldn't get canon WiX solutions to work). However, your suggestion leaves me with questions: how can an MSI "not know" about a file? I guess I'm asking you to expand a little on your post. Could you do that? – Bob Oct 16 '17 at 14:46
  • A file created by your application or by a custom action rather then one created by the MSI. – Christopher Painter Oct 16 '17 at 14:49
  • Consider this.. let's say your config had some key value pairs in build one. Lets say the user set one of those values to something. Now a newer build adds an additional key value pair. What should the installer do during upgrade? Overwrite and get the new KVP but lose the user data or not overwrite and save the user data but not get the new KVP? You could write complex custom actions to harvest the deltas, replace the file and reapply them or you could just eliminate the whole problem by storing the data in two files. Make sense? – Christopher Painter Oct 16 '17 at 14:51
  • The problem is that fundamentally windows installer doesn't apply the component rules at a granular enough level to handle XML files like it does for registry keys/values. – Christopher Painter Oct 16 '17 at 14:52
  • Yes, that makes sense. I was thinking about creating convoluted custom actions, but that's a much simpler, cleaner approach. – Bob Oct 17 '17 at 12:07