rkhj
rkhj

Reputation: 91

Wix - Upgrade always runs older installer msi and fails in trying to read old msi

I'm having a problem though with the Windows caching of the installer. I'm trying to do an upgrade and each time the Windows installer is launching the installer of the older version. And when I do the upgrade it is complaining about problems with reading the older version's msi file (because its not in the same directory anymore).

I did change the UpgradeCode and the ProductCode but kept the PackageCode the same. I also have different ProductVersion codes (2.2.3 vs 2.3.0).

Here's a sample of my code:

<Upgrade Id="$(var.UpgradeCode)">
      <UpgradeVersion Property="OLDAPPFOUND"
                  IncludeMinimum="yes"
                  Minimum="$(var.RTMProductVersion)"
                  IncludeMaximum="no"
                  Maximum="$(var.ProductVersion)"/>
  <UpgradeVersion Property="NEWAPPFOUND"
                  IncludeMinimum="no"
                  Minimum="$(var.ProductVersion)"
                  OnlyDetect="yes"/>
</Upgrade>

This is the Install Sequence:

<InstallExecuteSequence>
    <Custom Action='SetUpgradeParams' After='InstallFiles'>Installed AND NEWAPPFOUND</Custom>
      <Custom Action='Upgrade' After='SetUpgradeParams'>Installed AND NEWAPPFOUND</Custom>
   </InstallExecuteSequence>

The error I am getting is:

A network error occurred while attempting to read from the file:

Thanks,

Upvotes: 4

Views: 3925

Answers (4)

saschabeaumont
saschabeaumont

Reputation: 22406

Do NOT keep the same PackageCode.

You really want to have this automatically generated... refer the documentation:

Nonidentical .msi files should not have the same package code. It is important to change the package code because it is the primary identifier used by the installer to search for and validate the correct package for a given installation. If a package is changed without changing the package code, the installer may not use the newer package if both are still accessible to the installer.

Here's an example from our production environment...

<Product Id="*"
         UpgradeCode="$(var.Property_UpgradeCode)"
         Name="!(loc.ApplicationName)"
         Language="!(loc.Property_ProductLanguage)"
         Version="$(var.version)"
         Manufacturer="!(loc.ManufacturerName)" > 

<Package Description="!(loc.Package_Description) $(var.version)"
   Comments="!(loc.Package_Comments)"
   Manufacturer="!(loc.ManufacturerName)"
   InstallerVersion="301"
   Compressed="yes"
   InstallPrivileges="elevated"
   InstallScope="perMachine"
   Platform="$(var.ProcessorArchitecture)" />

Now the downside of this approach is it means you probably also want to enforce major upgrades, which only care about the upgrade code being referenced. Now we can take advantage of the fact that for Windows Installer packages only the first three fields are significant, e.g. 1.0.0.1 and 1.0.0.2 both are interpreted as 1.0.0 (this is explicitly mentioned in the documentation, so we can rely on it.)

Extending this logic, we can auto-increment the (ignored) fourth version field with every build but prevent upgrade when the first three are the same.

    <UpgradeVersion Property="ANOTHERBUILDINSTALLED"
             Maximum="$(var.version)" Minimum="$(var.version)"
             IncludeMinimum="yes" IncludeMaximum="yes" OnlyDetect="yes" />

The upside is this is completely transparent to customers, but prevents internal test/QA teams from installing one "build" on top of another and you also need to ensure that immediately following any public release you manually increment one of the first three version fields.

Upvotes: 3

Charles Gargent
Charles Gargent

Reputation: 1807

What does your product element say?

You need to specify the same upgrade code in the upgrade table and the product table ie

<Product 
   Id="..." 
   Language="..." 
   Manufacturer="..." 
   Name="..." 
   UpgradeCode="$(var.UpgradeCode)" 
   Version="..."
>

and it needs to be in the original one aswell if it wasnt originally specified there then maybe you can run a CA to remove it with shell command.

Apart from that it all looks ok.

In the log does it say anything in the "Findrelatedproducts" section?

Upvotes: 0

rkhj
rkhj

Reputation: 91

Here's the source code (or as much of it as I can give):

http://schemas.microsoft.com/wix/2003/01/wi'>

.....

<Package Id='$(var.PackageCode)'
         Comments='$(var.App_LongName)'
         Description='$(var.App_LongName) setup package'
         Manufacturer='$(var.Manufacturer)'
         InstallerVersion='200'
         Languages='1033'
         SummaryCodepage='1252'
         Compressed='yes'
         Keywords='Installer,$(var.App_ShortName)' />

<FragmentRef Id='AppInstaller.UI' />

<!-- Upgrade table -->
<Upgrade Id="$(var.UpgradeCode)">

  <UpgradeVersion Minimum="$(var.ProductVersion)"
                  IncludeMinimum="no"
                  OnlyDetect="yes"
                  Property="NEWPRODUCTFOUND" />
  <UpgradeVersion Minimum="$(var.RTMProductVersion)"
                  IncludeMinimum="yes"
                  Maximum="$(var.ProductVersion)"
                  IncludeMaximum="no"
                  Property="UPGRADEFOUND" />

</Upgrade>

.....


<!-- Prevent downgrading -->
<CustomAction Id="NewerVersionDetected" Error="$(loc.App_WixUI_NewerVersionDetected)" />

......

<CustomAction Id="SetDeployParams" Return="check" Property="Deploy" Value="Deploy|[DB_USER]|[DB_PW]|[DB_PORT]|[WS_USER]|[WS_PW]|[WS_PORT]|[PROTOCOL]|[HOST]|[TIMEOUT]|[#App.WAR]|[#CONTEXT.XML]" />
<CustomAction Id="Deploy" JScriptCall="main" Property="Script" Execute="deferred" Return="check" />
<CustomAction Id="SetRollbackParams" Return="check" Property="RollbackDeploy" Value="Rollback|[DB_USER]|[DB_PW]|[DB_PORT]|[WS_USER]|[WS_PW]|[WS_PORT]|[PROTOCOL]|[HOST]|[TIMEOUT]|[#App.WAR]|[#CONTEXT.XML]" />
<CustomAction Id="RollbackDeploy" JScriptCall="main" Property="Script" Execute="rollback" />
<CustomAction Id="SetUnDeployParams" Return="check" Property="UnDeploy" Value="Undeploy|[DB_USER]|[DB_PW]|[DB_PORT]|[WS_USER]|[WS_PW]|[WS_PORT]|[PROTOCOL]|[HOST]|[TIMEOUT]|[#App.WAR]|[#CONTEXT.XML]" />
<CustomAction Id="UnDeploy" JScriptCall="main" Property="Script" Execute="deferred" Return="check" />
<CustomAction Id="SetRepairParams" Return="check" Property="Repair" Value="Repair|[DB_USER]|[DB_PW]|[DB_PORT]|[WS_USER]|[WS_PW]|[WS_PORT]|[PROTOCOL]|[HOST]|[TIMEOUT]|[#App.WAR]|[#CONTEXT.XML]" />
<CustomAction Id="Repair" JScriptCall="main" Property="Script" Execute="deferred" Return="check" />
<CustomAction Id="SetUpgradeParams" Return="check" Property="Upgrade" Value="Upgrade|[DB_USER]|[DB_PW]|[DB_PORT]|[WS_USER]|[WS_PW]|[WS_PORT]|[PROTOCOL]|[HOST]|[TIMEOUT]|[#App.WAR]|[#CONTEXT.XML]" />
<CustomAction Id='Upgrade' JScriptCall="main" Property="Script" Execute="deferred" Return="check" />
<CustomAction Id="PreventDowngrading" Error="Newer version already installed." />

<InstallUISequence>
  <FindRelatedProducts Sequence="200" />
  <Custom Action="PreventDowngrading" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
</InstallUISequence>

<InstallExecuteSequence>
  <LaunchConditions After='AppSearch'></LaunchConditions>
  <RemoveExistingProducts After='InstallFinalize' />

  <Custom Action='SetUrl' Before='InstallFiles' />
  <Custom Action='SetSecurePort' After='LaunchConditions'>PROTOCOL = "secure"</Custom>
  <Custom Action='SetNonSecurePort' After='LaunchConditions'>NOT (PROTOCOL = "secure") OR NOT PROTOCOL</Custom>

  <Custom Action='SetDeployParams' After='InstallFiles'>NOT Installed AND NOT PATCH</Custom>
  <Custom Action='Deploy' After='SetDeployParams'>NOT Installed AND NOT PATCH</Custom>

  <Custom Action='SetRollbackParams' Before='RollbackDeploy'>NOT Installed AND NOT PATCH</Custom>
  <Custom Action='RollbackDeploy' Before='Deploy'>NOT Installed AND NOT PATCH</Custom>

  <Custom Action='SetUpgradeParams' After='InstallFiles'>Installed AND UPGRADEFOUND</Custom>
  <Custom Action='Upgrade' After='SetUpgradeParams'>Installed AND UPGRADEFOUND</Custom>

  <Custom Action='SetRepairParams' After='InstallFiles'>Installed AND NOT REMOVE="ALL" AND NOT NEWAPPFOUND</Custom>
  <Custom Action='Repair' After='SetRepairParams'>Installed AND NOT REMOVE="ALL" AND NOT NEWAPPFOUND</Custom>

  <Custom Action='SetUnDeployParams' After='MsiUnpublishAssemblies'>Installed AND REMOVE="ALL" AND NOT NEWAPPFOUND</Custom>
  <Custom Action='UnDeploy' After='SetUnDeployParams'>Installed AND REMOVE="ALL" AND NOT NEWAPPFOUND</Custom>

  <Custom Action="PreventDowngrading" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>

</InstallExecuteSequence>

Upvotes: 0

Charles Gargent
Charles Gargent

Reputation: 1807

You need to keep the upgrade code the same and change the product code (if you want an upgrade).

In the InstallExecuteSequence you need the following line

<RemoveExistingProducts After="InstallInitialize" />

I have chosen to put the action after the installInitialize sequence in this example however you can place them in other locations which will give you different effects.

This is a good reference

Upvotes: 2

Related Questions