Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSI Major Upgrade overwriting rules

I think I read it somewhere, but couldn't find the source now and can't confirm it: when install(Major upgrade) a newer version from MSI, if the file has been modified (either by installer or user), the default rule is that old file wouldn't be replaced by the same file from a new version?

I think also I observed that behavior in the installer I wrote before, but now after a few changes, seems that it will always replace the old modified config files!

Product definition:

    <Product Id="*" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="Advanced Software Solution" UpgradeCode="$(var.UpgradeCode)">
        <Package Id="*"  InstallerVersion="200" Description="The web service installer" Compressed="yes" 
             InstallScope="perMachine"/>
    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />

Component Definition:

<Component Id='WebConfigComp' Guid='GUID'>
        <File Id='WebConfigFile' Name='Web.config' Source='$(var.TheWebService.WCF.TargetBinPath)\Web.Distribution.config'
              KeyPath='yes'>
        </File>
      </Component>

InstallExecutesequence

FindRelatedProducts     25
AppSearch               50
LaunchConditions        100
ValidateProductID       700
myScripts_CA            799
CostInitialize          800
FileCost                900
CostFinalize            1000
MigrateFeatureStates    1200
InstallValidate         1400
RemoveExistingProducts  1401
InstallInitialize       1500
BackupCA    Installed   1501
ProcessComponents       1600
UnpublishFeatures       1800
SchedSecureObjectsRollback_x64  VersionNT > 400 1801
RemoveFiles         3500
RemoveFolders       3600
CreateFolders       3700
InstallFiles        4000
InstallServices VersionNT   5800
SchedSecureObjects_x64  NOT REMOVE~="ALL" AND VersionNT > 400   5801
ConfigureIIs    NOT SKIPCONFIGUREIIS AND VersionNT > 400    5999
RegisterUser        6000
RegisterProduct     6100
PublishFeatures     6300
PublishProduct      6400
InstallFinalize     6600
LunchWCFReadme  NOT Installed   6601

Update: I just created a new project for testing, the same behavior observed (the modified file is replaced by the newer version of installer) without change the default InstallExecSequence. Which probably means even though the File Versioning should applies, but it not actually kicked in to affect the result would expected as Remove of old version happened too early be default as Glytzhkof and PhilDW pointed out.

I am using Wix 3.8, the current stable, did I missed something?

Update2: So far, I can confirm that moving RemoveExistingProducts after InstallFiles will keep the modified unversioned files. But the problem is that seems MajorUpgrade conflict with

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

I am adding, and the error message is

Error 1 Duplicate symbol 'WixAction:InstallExecuteSequence/RemoveExistingProducts' found. This typically means that an Id is duplicated. Check to make sure all your identifiers of a given type (File, Component, Feature) are unique. C:\TestDev\MySetupTest\MySetupTest\Product.wxs 5 1 MySetupTest

which is not very helpful either.

Final Update: After digging the web thing for a while, find out what the issue is:

By default, MajorUpgrade schedules RemoveExistingProducts after InstallValidate. You can change the scheduling using the Schedule attribute. For example, If you choose to schedule it after InstallInitialize, it will look like the following:

<MajorUpgrade
  Schedule="afterInstallInitialize"
  DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit.">

Source: Wix Toolset website

So including of MajorUpgrade will indeed change RemoveExistingProducts sequence for you, which is a useful feature to have, but was unexpected for me. Thanks for all the help, now things starting make sense to me. An happy ending after all!

like image 795
Paul L Avatar asked Mar 04 '14 00:03

Paul L


People also ask

What is a major upgrade?

A major upgrade is a comprehensive update of a product that needs a change of the ProductCode Property. A typical major upgrade removes a previous version of an application and installs a new version.

What is upgrade table in MSI?

The Upgrade table contains information required during major upgrades. To fully enable the installer's upgrade capabilities, every package should have an UpgradeCode property and an Upgrade table.


2 Answers

When a major upgrade uninstalls an existing installation before the new version gets installed (RemoveExistingProducts before InstallInitialize) it will normally remove all files that were originally installed - this includes files that may have been modified. Then the new version is installed with a fresh bundle of files.

If you schedule RemoveExistingProducts after InstallFinalize the install of the new version's files precedes the removal of obsolete files. In this scenario files are only replaced if they are versioned and newer than installed files, and for unversioned files like txt, pdf, etc... the file replacement rules basically states that the file will only be overwritten if it has not been changed on disk.

It follows that moving RemoveExistingProducts after InstallFinalize may solve your file "replacement problem" which is really a case of the modified files being deleted during uninstalland reinstalled by your current upgrade strategy.

like image 83
Stein Åsmul Avatar answered Oct 11 '22 22:10

Stein Åsmul


As pointed out, your REP is early in the sequence, so it's essentially an uninstall of all the older product followed by an install of the new one. This is one type of major upgrade.

The other type of major upgrade is when REP is at the "end". In this case the new product is installed on top of the older product, and that will follow file replacement rules, that's the part that's relevant to your question.

This might be useful:

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

and there's different rule if the unversioned files have hash checking. Yes, unversioned means "without a file version in the file's resources".

like image 36
PhilDW Avatar answered Oct 12 '22 00:10

PhilDW