2

Related to: How to keep a config file when major upgrade in wix v3.8?

Referencing: http://blogs.msdn.com/b/astebner/archive/2008/10/19/9006538.aspx, http://wixtoolset.org/documentation/manual/v3/howtos/updates/major_upgrade.html, http://www.joyofsetup.com/2010/01/16/major-upgrades-now-easier-than-ever/

If I employ <MajorUpgrade DowngradeErrorMessage="A newer version is already installed." Schedule="afterInstallInitialize" /> then the installer works almost as hoped, except that the config file and everything else is removed before the new product files are installed. I totally get that afterInstallInitialize specifies this behavior.

Yet I want to retain the .config file if it has been modified (if the create date and modified date are different) so I set it to keyPath='yes' and attempt to schedule the RemoveExisingProducts to after the reference counts have been incremented with Schedule='afterInstallExecute'.

But when I use afterInstallExecute, it does not behave as I expect during upgrades (works fine as a fresh install). Instead of overwriting the new versions of files that are not marked keyPath='yes' (everything else), all the existing files are left unmodified as their old versions. The installer thinks it was successful anyway.

Each file in my wix has its own component such as:

<Component Id="Host" Guid='*' Win64='yes'>
    <File Source='$(var.root)MyLib.dll' />
</Component>

And:

<Product Id="$(var.productCode)" Language="1033" 
    Version="$(var.version)" UpgradeCode="$(var.upgradeCode)">
    <Package Id="*" InstallerVersion="405" Compressed="yes" Platform="x64"
        InstallPrivileges="elevated" InstallScope="perMachine" />

I'm using WiX 3.8 and the Burn bootstrapper, but if I run the msi without the bootstrapper there's no change. InstallerVersion="405" vs 200 makes no difference.

I don't see any conditions like "skip if already installed" kind of stuff.

What else should I be looking for? Is what I describe the expected behavior?

Thanks!

Note: My Product Version is of the form 0.0.238 and increments with every build. So this should be OK single I'm only using the first three version components.

Here are some highlights from my log file:

  • Allowing installation of component: {...} even though a modified unversioned keyfile exists and file versioning rules would disable the component
  • ... Won't Overwrite; Won't patch; Existing file is unversioned but modified (for my one .config file. CORRECT!)
  • ... Won't Overwrite; Won't patch; Existing file is of an equal version (mostly for DLLs and EXEs)
  • ... Won't Overwrite; Won't patch; Existing file is unversioned and unmodified - hash matches source file (mostly for PDBs and XML)

If I specify the -sf linker option, to perhaps force the file version numbers to match the Product's overall version number (as far as Windows Installer is concerned) then the GAC installation fails with "Unknown table 'MsiAssemblyName' in SQL query: SELECT Value FROM MsiAssemblyName". So -sf probably isn't the right trick.

I think I want to avoid updating the .NET assembly version numbers with every build as long as the interfaces don't change and they're just bug fixes. That will make replacement on the installation machine more automatic, right? I'm not even sure if the assembly version change is what's necessary, but I'm fighting it anyway. :-)

Jason Kleban
  • 20,024
  • 18
  • 75
  • 125
  • Check the log if you are setting a custom REINSTALLMODE value: http://msdn.microsoft.com/en-us/library/aa371182(v=vs.85).aspx . Try adding REINSTALLMODE=emus on the command line for the upgrade. – Stein Åsmul Apr 02 '14 at 11:06

1 Answers1

1

I am a bit confused reading this, but provided you have followed the component creation rules you can move RemoveExistingProducts after InstallFinalize. This will remove the old version after installing new files from the new version. This only works properly if the component referencing is correct, but will preserve changed files.

Inserting RemoveExistingProducts early in the InstallExecuteSequence will remove the old version completely, and then reinstall all files - reverting them to default provided they were not set as permanent components in the previous version. I don't think I have ever used the position after InstallExecute - I think you may be mixing up the names.

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
  • [MajorUpgrade](http://wixtoolset.org/documentation/manual/v3/xsd/wix/majorupgrade.html) has the reference to `afterInstallExecute`. Those docs explain why I don't want to wait until after InstallFinalize - then it's out of the transaction. Also, as I understand it, MajorUpgrade actually reschedules it for you (using `Schedule` attribute) and that it would be wrong to use some other mechanism. I do not use `permanent`, just the `keyPath` which is supposed to check for modifications before overwrite. I expect the new versions to overwrite the old versions but they don't when keyPath is false – Jason Kleban Mar 31 '14 at 20:38
  • Guid='*' in the component element? I haven't used this Wix feature, but if this changes the GUID for every build then this will break all component referencing and cause this file replacement problem. See my answer here: http://stackoverflow.com/questions/1405100/change-my-component-guid-in-wix/1422121#1422121 – Stein Åsmul Apr 01 '14 at 10:11
  • [Documentation states](http://wixtoolset.org/documentation/manual/v3/howtos/general/generate_guids.html) "For the Component element the generated GUID is based on the install directory and filename of the KeyPath for the component. This GUID will stay consistent from build-to-build provided the directory and filename of the KeyPath do not change." Referring to `Guid='*'` of the Component, [also supported here](http://wixtoolset.org/documentation/manual/v3/xsd/wix/simple_type_componentguid.html): "the default value is '*' which indicates that the linker should generate a stable guid." – Jason Kleban Apr 01 '14 at 11:29
  • I do appreciate your attention to this. Thank you. – Jason Kleban Apr 01 '14 at 13:00
  • 1
    Get a verbose log and see what's going on. Everything looks ok at first glance, If you're using the WiX majorupgrade element the REP will be done just before InstallFinalize. Note that overwriting of files isn't specifically to do with keyfiles, it's more about incrementing each file version of binaries you want to be updated, part of the file overwrite rules that apply during the late REP. – PhilDW Apr 01 '14 at 17:30
  • @PhilDW - Thanks! I've added my log details to the Question. Do I have to also update all the assembly versions with every bug fix? Maybe that's a stupid question, but updating the assembly versions seems easily forgettable as a build step and/or troublesome for install-side assembly version bindings (which wouldn't otherwise need to be told of an internal bug fix on a DLL, for example). Or is this a WiX binary version concept unrelated to the .NET assembly version. But where is that set? I don't see `Version` as an attribute on Components or Files. – Jason Kleban Apr 01 '14 at 18:40
  • 1
    You need to increment file versions to get them updated during a patch or during an upgrade with REP at the end. That's not a WiX thing, it's the version in the files when you build them. For assemblies that's not the same as the assembly version - see assemblyfileversion to increment file version without changing assemblyversion. If the upgrade is removing the old entry in programs and features then the upgrade is working, and the filecopy log entries in a log should say that files are being overwritten because the incoming files have higher versions. – PhilDW Apr 02 '14 at 16:57
  • 1
    He should be able to make do with REINSTALLMODE=emus I think. – Stein Åsmul Apr 02 '14 at 20:39
  • guys, I have the incrementing AssemblyFileVersion solution is pending, but I have an unrelated hangup to resolve before I can verify that this one is resolved. @Glytzhkof, you might be right about `emus` and it's a pain in the butt to keep those numbers incrementing (even with automated assistance) but I think that's the right way from an overall product management perspective. I'll report back. – Jason Kleban Apr 02 '14 at 21:31
  • It was certainly the assemblyfileversion. Now that I have those incrementing the installer is updating modified key files and overwriting others. – Jason Kleban Apr 06 '14 at 02:16