Wix MajorUpgrade not working, after changing UpgradeCode GUID & Version - wix

We are using the following code in our Wix Packages.wxs file, as per the documentation we are changing the UpgradeCode GUID & Version number from. 1.0.1.0 to 1.0.2.0 but when we build and try to install the msi package it says older version is still installed and we need to uninstall it to continue.
<Product Id="8B3DFDFF-D894-4A31-AA92-824729385F15" Name="WixCodeBase" Language="1033" Version="1.0.2.0" Manufacturer="Company Name" UpgradeCode="C78D9362-A156-44A2-94D0-AFA19389FFE8">
<Package Id="*" Keywords="Installer" Manufacturer="Company Name" Description="Wix Installer" InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade Schedule ="afterInstallValidate" AllowDowngrades="no" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Media Id='1' Cabinet='WixPackage.cab' EmbedCab='yes' />
Installer Error

For major upgrades, you change the Product element's Id attribute not the UpgradeCode attribute. In fact, UpgradeCode attribute must remain constant across versions to use the MajorUpgrade element. MSDN has all the details.

I maintain an open source project called IsWiX that provides templates and designers to accelerate the WiX / MSI learning and development process. One of the many things these templates do out of the box is provide proper Major Upgrade support. Consider this code generated by the template:
Code Source
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<!--
MSIProductVersion is defined in DesktopApplication.wixproj as 0.0.1 for local desktop builds.
You should pass in the MSBuild Property 'MSIProductVersion' to override it during an automated build.
See http://msdn.microsoft.com/en-us/library/windows/desktop/aa370859%28v=vs.85%29.aspx for information on allowable values.
The Product#Id attribute (ProductCode Property) will be a random GUID for each build. This is to support "Major Upgrades" where each install
is a seamless uninstall/reinstall.
-->
<Product Id="*" Name="DesktopApplication" Language="1033" Version="$(var.MSIProductVersion)" Manufacturer="DesktopApplication" UpgradeCode="7220a19b-ed49-4cd1-8002-6af7926441b4">
<Package InstallerVersion="301" Compressed="yes" InstallScope="perMachine" />
<MediaTemplate EmbedCab="yes" />
<!-- Major Upgrade Rule to disallow downgrades -->
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<!--Common Launch Condition-->
<!-- Examples at http://wixtoolset.org/documentation/manual/v3/customactions/wixnetfxextension.html -->
<PropertyRef Id="NETFRAMEWORK40FULL"/>
<Condition Message="[ProductName] requires .NET Framework 4.0.">Installed OR NETFRAMEWORK40FULL</Condition>
<!-- Include User Interface Experience -->
<Icon Id="Icon.ico" SourceFile="Resources\Icon.ico"/>
<Property Id="ARPPRODUCTICON" Value="Icon.ico"></Property>
<UIRef Id="UI"/>
<!-- Include Features and Directories Fragment -->
<DirectoryRef Id="INSTALLLOCATION"/>
</Product>
</Wix>
In addition to be documented in the comments, it's also discussed in the tutorials.
In a nutshell, you need to keep UpgradeCode the same and randomize ProductCode.

Related

WiX upgrade doesn't work after changing from per machine to per user installation. How can I uninstall the old version?

WiX Toolset Version: 3.11.2.4516
To switch from a per machine to a per user installation, I changed my WiX configuration from this:
<Product Id="*" Name="$(var.ProductName)" Language="1033" Version="1.0.0.1"
Manufacturer="$(var.CompanyName)" UpgradeCode="eec853e6-9345-4be0-908f-958f212c6f30">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" InstallPrivileges="elevated" />
<MajorUpgrade Schedule="afterInstallInitialize"
DowngradeErrorMessage="A newer version of $(var.ProductName) is already installed" />
To this (remove Package/#InstallScope and Package/#InstallPrivileges):
<Product Id="*" Name="$(var.ProductName)" Language="1033" Version="2.0.0.0"
Manufacturer="$(var.CompanyName)" UpgradeCode="eec853e6-9345-4be0-908f-958f212c6f30">
<Package InstallerVersion="200" Compressed="yes" />
<MajorUpgrade Schedule="afterInstallInitialize"
DowngradeErrorMessage="A newer version of $(var.ProductName) is already installed" />
Now the product is installed per user instead of per machine. But the <MajorUpgrade> doesn't work anymore. I also tried to change the Product/#UpgradeCode to a new GUID and add the following to my WiX config (below the <MajorUpgrade> element):
<Upgrade Id="eec853e6-9345-4be0-908f-958f212c6f30">
<UpgradeVersion OnlyDetect="no" Property="OLD_SERVICE_INSTALLER_FOUND" Minimum="0.0.0.0" />
</Upgrade>
But that doesn't work either.
How can I uninstall the old version of my software, if I switched from per machine to per user installation?
Your stuck. This is a windows installer limitation.
https://learn.microsoft.com/en-us/windows/win32/msi/major-upgrades
Note
If an application is installed in the per-user installation context,
any major upgrade to the application must also be performed using the
per-user context. If an application is installed in the per-machine
installation context, any major upgrade to the application must also
be performed using the per-machine context. The Windows Installer will
not install major upgrades across installation context.

Wix MSI installer is not removing previous version from "Add/Remove Applications" when updating the application

I have created a new installer with a new version and Product ID with no errors but when it is installed, the current version remains installed as well as the updated version. I have been using this for a while to install and update my application on different machines but only recently has it started to not delete the old version completely. I have updated the .wxs file as follows:
1. Changed <Product Id="{F9030CA1-39AD-46BD-B2E2-3DBE02A8845B}".
2. Updated the new version number.
I have not updated the Upgrade Code.
I have created multiple versions of the installer to see if the problem persist and it seems as it does. I have also updated the Wix extension to visual studio (Votive2019) but no luck.
Not sure if there is a fault with my code or if this is a bug. I am not even sure what the cause of this problem is.
Below is a snippet of my code from the package section:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="{F9030CA1-39AD-46BD-B2E2-3DBE02A8845B}" Codepage="1252" Language="1033" Manufacturer="Mi-Plan" Name="FD to Excel" UpgradeCode="{17469B04-7B24-455E-BCB8-CD7AEA97CDCD}" Version="10.0.560">
<Package Compressed="yes" Description="10.0.560.0" InstallerVersion="200" Languages="1033" Manufacturer="Jwayela Software" Platform="x86" />
Below is a snippet of my code from the upgrade section:
<Upgrade Id="{A39F99F9-069F-4356-AA6A-5BBBC6DADB29}">
<UpgradeVersion Maximum="10.0.560" Property="PREVIOUSVERSIONSINSTALLED" />
<UpgradeVersion Minimum="10.0.560" Property="NEWERPRODUCTFOUND" OnlyDetect="yes" IncludeMinimum="yes" />
</Upgrade>
I am using Visual Studio 2019.
Click here to get full file.
Type Mismatch Error: It looks like there is a mismatch between the Upgrade element's "Id" value and the Upgrade Code you have specified in the Product element? That would explain why the major upgrade doesn't work, but not why it has worked so far?
Major Upgrade Element: Would recommend you use the simplified major upgrade element if you don't need fine grained control in the Upgrade table for something special. I just wrote an answer for this a few hours ago: Unable to remove previous versions of MSI. Multiple entry's show up in control panel. Magixal MajorUpgrade element - this single, simple line does all the work for you:
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
Define: Another thing is that Defines can be used to set values that are to be used in different places in the source and need to match exactly all the time:
<?define MyProductVersion = "31.00.0000" ?>
<?define MyProductCode = "PUT-GUID-HERE" ?>
<?define MyUpgradeCode = "PUT-GUID-HERE" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="$(var.MyProductCode)" Codepage="1252" Language="1033" Manufacturer="Corp"
Name="Bla" UpgradeCode="$(var.MyUpgradeCode)" Version="$(var.MyProductVersion)">
<...>
<!-- Major upgrade -->
<Upgrade Id="$(var.MyUpgradeCode)">
<!-- Downgrade Protection -->
<UpgradeVersion Minimum="$(var.MyProductVersion)" OnlyDetect="yes"
IncludeMinimum="yes" Property="DOWNGRADE_DETECTED" />
<!-- Major Upgrade Configuration -->
<UpgradeVersion IncludeMinimum="no" Maximum="$(var.MyProductVersion)"
IncludeMaximum="no" MigrateFeatures="yes" Property="UPGRADE_DETECTED" />
</Upgrade>
</Wix>

WiX: Conditionally including UpgradeCode in WiX file

I'm using WiX to build an installation package for a product at my company and I want to be able to build two slightly different versions of the .msi depending on if it is meant to be used internally in the company for testing or externally for customers.
The internal version should be built with no UpgradeCode, so that we can have several versions installed at the same time for comparison. The external version should have a static UpgradeCode.
WiX does not allow me to have UpgradeCode auto generated by doing this:
<?if $(var.Configuration) = "Internal Release"?>
<?define UpgradeCode = "*"?>
<?else?>
<?define UpgradeCode = "[REALGUID]"?>
<?endif?>
<Product ... UpgradeCode="$(var.UpgradeCode)">
To have the UpgradeCode "auto generated" you have to completely ommit the UpgradeCode attribute.
Anyone have any suggestions on how to accomplish this?
Probably you can't use * for Upgrade Code (i'm not sure) but you could pass it as property through msbuild which i do for ProductCode conditionaly (if we are building patches or not)
<UpgradeCode Condition="$(InternalRelease)==1">{$([System.Guid]::NewGuid().ToString().ToUpper())}</UpgradeCode>
In your msbuild.proj add that property in your Target/msbuild project/Properties.
Add UpgradeCode=$(UpgradeCode) in you constants (wixproj)
Then in your main wxs add something like this:
<?if $(var.UpgradeCode)=""?>
<?define UpgradeCode=your-static-upgradecode ?>
<?endif?>
So if the project receives the upgrade code then it will use that one otherwise will be your fixed upgrade code in defined.
And finally to generated the guid call the msbuild.proj with /p:InteralRelease=1
Adding this answer as an alternative solution for other users with the same challenge.
Altough IlirB's answer probably would work as expected (I haven't tried it as I solved the problem with my own solution before the answer was provided), I solved the problem by conditionally including one of 2 different versions of the Product-tag. Of which only one had the UpgradeCode defined.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include Config.wxi?>
<?if $(var.IsExternalRelease) = yes?>
<Product Id="$(var.ProductID)" Name="$(var.ProductName)" Language="1033" Version="$(var.Version)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">
<Package Id="$(var.PackageID)" InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<PropertyRef Id="AllProperties"/>
<UIRef Id="CUSTOM_UI"/>
<FeatureRef Id="F_AllFeatures"/>
</Product>
<?else?>
<Product Id="$(var.ProductID)" Name="$(var.ProductName)" Language="1033" Version="$(var.Version)" Manufacturer="$(var.Manufacturer)">
<Package Id="$(var.PackageID)" InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MediaTemplate EmbedCab="yes"/>
<PropertyRef Id="AllProperties"/>
<UIRef Id="CUSTOM_UI"/>
<FeatureRef Id="F_AllFeatures"/>
</Product>
<?endif?>
</Wix>
Because I made an effort in splitting the wix code into several pieces and referring them from the Product tag, there was not much duplication of code.

How to get WiX major upgrade working?

I am struggling to enable the major upgrade functionality in WiX.
I want every new version of the installer to be a major upgrade (full uninstall, then new install) as we don't want different upgrade and clean install versions.
I started off trying to do it using the tag stuff, but I kept getting "Another version is installed." error message when I run the installer.
So I implemented the new tag that was added in V3.5 to make upgrades easier. I was still getting the error message.
I then read somewhere that you need to change the Id GUID for each new version. So I set Id="*" to get WiX to generate them.
Now when I install the newer version it doesn't uninstall the older version, and you end up with two installations to the same folder. I worked this out because running either MSI (new or old) would bring up the repair/remove screen.
Also the program was not overwritten with the new version.
Here is the start of my WiX script:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*"
Name="Foo"
Language="1033"
Codepage="1252"
Version="!(bind.FileVersion.Foo.exe)"
Manufacturer="Foo Bar Ltd."
UpgradeCode="dac2fab2-7d76-4e47-b25f-0748380dab81">
<Package
Description="Foo"
Comments="This installer database contains the logic and data required to install Foo."
InstallerVersion="300"
Languages="1033"
SummaryCodepage="1252"
Platform="x86"
Compressed="yes" />
<!-- Remove older versions -->
<!-- Important note: MSI ignores the last version digit 1.0.0.? when comparing versions, so always change at least the 3rd digit for new external releases-->
<MajorUpgrade DowngradeErrorMessage="The version currently installed is newer than the version you are attempting to install."/>
Here's a snippet of what I use for all my packages, refined over many internal and public releases
<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)" />
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<Upgrade Id="$(var.Property_UpgradeCode)">
<UpgradeVersion OnlyDetect="yes"
Minimum="$(var.version)"
Property="NEWERVERSIONDETECTED"
IncludeMinimum="no" />
<UpgradeVersion OnlyDetect="no"
Maximum="$(var.version)"
Property="OLDERVERSIONBEINGUPGRADED"
IncludeMaximum="no" />
<!-- Detect for changes in 4th field only -->
<UpgradeVersion Property="ANOTHERBUILDINSTALLED"
Maximum="$(var.version)" Minimum="$(var.version)"
IncludeMinimum="yes" IncludeMaximum="yes" OnlyDetect="yes" />
</Upgrade>
<CustomAction Id="CA_BlockOlderVersionInstall" Error="!(loc.LaunchCondition_LaterVersion)" />
<CustomAction Id="CA_BlockAnotherBuildInstall" Error="!(loc.LaunchCondition_AnotherBuild)" />
<InstallExecuteSequence>
<Custom Action="CA_BlockOlderVersionInstall" After="FindRelatedProducts">
<![CDATA[NEWERVERSIONDETECTED]]>
</Custom>
<!-- Prevent installation on 4th version field change only -->
<Custom Action="CA_BlockAnotherBuildInstall" After="FindRelatedProducts">
<![CDATA[ANOTHERBUILDINSTALLED]]>
</Custom>
<LaunchConditions After="AppSearch" />
<!-- Schedule RemoveExistingProducts early -->
<RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>
<InstallUISequence>
<Custom Action="CA_BlockOlderVersionInstall" After="FindRelatedProducts">
<![CDATA[NEWERVERSIONDETECTED]]>
</Custom>
<!-- Prevent installation on 4th version field change only -->
<Custom Action="CA_BlockAnotherBuildInstall" After="FindRelatedProducts">
<![CDATA[ANOTHERBUILDINSTALLED]]>
</Custom>
<LaunchConditions After="AppSearch" />
</InstallUISequence>
<!-- .... -->
</Product>
If it's of any use to those who discover this thread, I've also encountered a similar problem which I've just figured out.
In my case (and still having been in early stages of developing my installer), the critical difference was that, between versions, I had switched from a per-user install to a per-machine install. More specifically, I'd added the following line to my Product.wxs:
<Property Id='ALLUSERS' Value='1'/>
I'm still getting my head around many of the idiosyncrasies of Windows Installers, but I'd assume that by switching the type of installation in this way would be comparable with shifting to a mutually exclusive stream of versioning in many ways (even enabling two identical versions to be installed in parallel!).
It's a shame that the Windows Control Panel doesn't clearly distinguish between installations which are per-user and all-users.
I know this post is old and answered, but, in case anyone runs across this, I had issues with my upgrade installer. The upgrade sections were all fine. The installer would run, but, the previous version was never removed, therefore, the new version was not installed. The issue was this
<Feature Id="ProductBinaries" Title="ProductBinariesInstaller" Level="0">
The Level="0" above, should have been Level="1" as it is below:
<Feature Id="ProductBinaries" Title="ProductBinariesInstaller" Level="1">
Scott

How to get Wix to update a previously installed version of a program

I wrote an install program with Wix and it worked fine to install my program.
Now I need to update it, so I bumped up the version number but when I go to install the new program over the old one it complains that an older version is already installed and tells me to uninstall it first.
How do I get it to update or automatically uninstall it before reinstalling?
I feel that none of the provided answers are complete or self-contained, so after digging my way through this swamp, here's the steps I think are necessary to get the (utterly self-evident) requirement of an update to work:
Make sure your Product Id changes every time you build. If you don't, you'll always get the "already installed" message the OP mentioned.
<Product Id="*" ...>
Change the Product Version every time the product itself changes. I suppose the best option is to bind it to an assembly version (which should be auto-incremented as well), but of course you could also just change it manually. This step is not strictly required if you use the AllowSameVersionUpgrades attribute in point 4, but I'd venture to say that keeping your product version constant is bad practise in any case.
<Product Version="!(bind.FileVersion.MyAssemblyDll)" ...>
<File Id="MyAssemblyDll" Name="$(var.001_Application.MyAssembly.TargetFileName)" Source="$(var.001_Application.MyAssembly.TargetPath)" />
Keep your UpgradeCode constant (e.g.):
<Product UpgradeCode="f4d7f199-28f6-45d5-ad99-7c62938274be" ...>
Add the MajorUpgrade element (from Wix 3.5.1315.0). To circumnavigate the catch that the MajorUpgrade will disregard changes in the revision number of the product version, add the AllowSameVersionUpgrades (or if you prefer AllowDowngrades) attribute. This way, you will be able to upgrade from e.g. 1.0.0.7 to 1.0.0.8. and not just from 1.0.7.0 to 1.0.8.0. If you don't do this, you may see multiple installations in Programs and Features.
<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
Here's my whole .wix file (relevant parts, the two fragments that lead to the assembly which is used for product binding are mostly optional and for illustration, any way you can get a hold of the assembly will work):
<?xml version="1.0" encoding="UTF-8"?>
<?define ProductVersion="!(bind.FileVersion.MyAssemblyDll)"?>
<?define UpgradeCode="f4d7f199-28f6-45d5-ad99-7c62938274be"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
<Product
Id="*"
Name="My Product's name"
Language="1033"
Version="$(var.ProductVersion)"
Manufacturer="My company"
UpgradeCode="$(var.UpgradeCode)"
Codepage="1252">
<Package
InstallerVersion="200"
Compressed="yes"
InstallScope="perUser"
Description="My product description"
Manufacturer="My company"
Languages="1033"
SummaryCodepage="1252"
InstallPrivileges="limited" />
<MajorUpgrade AllowSameVersionUpgrades="yes"
DowngradeErrorMessage="A newer version of [ProductName] is already installed. If you are sure you want to downgrade, remove the existing installation via Programs and Features." />
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="LocalAppDataFolder">
<Directory Id="INSTALLFOLDER" Name="My Install Dir" >
<Component Id="INSTALLFOLDER" Guid="f6ba8a12-6493-4911-8edd-dce90e1d8e8b" >
<RemoveFolder On="both" Id="INSTALLFOLDER"/>
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]" Type="string" Value="My Registry value" />
</Component>
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" >
<Component Id="ProductComponent" Guid="1939f0f5-19f6-498b-bf95-8f1c81501294" DiskId="1" Directory="INSTALLFOLDER" >
<File Id="MyAssemblyDll" Name="$(var.001_MyApplication.MyAssembly.TargetFileName)" Source="$(var.001_MyApplication.MyAssembly.TargetPath)" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
I checked through all the posts mentioned above and still spent ages trying to get this to work.
The hint on the official HOWTO for upgrades in Step 3 helped a lot: You need a new Product/#Id to disable the message "Another version of this product is already installed".
I used this upgrade section (child of Product):
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Minimum="1.0.0"
IncludeMinimum="yes"
OnlyDetect="no"
Maximum="$(var.Version)"
IncludeMaximum="no"
Property="PREVIOUSFOUND" />
</Upgrade>
Note that OnlyDetect is set to "no". This triggers the removal of the old version, if you have the following section (child of Product):
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize"/>
</InstallExecuteSequence>
Also note that apparently, only the first three components of the version number are used to check for upgrades...
You need to use the upgrade table:
<Upgrade Id='15E2DAFB-35C5-4043-974B-0E342C25D76A'>
<UpgradeVersion Property='OLDVERSIONFOUND' IncludeMinimum='no' Minimum='0.0.0.0' />
</Upgrade>
You need also add an action:
<InstallExecuteSequence>
<LaunchConditions After='AppSearch' />
<RemoveExistingProducts After='InstallValidate' />
</InstallExecuteSequence>
Here is a tutorial
I tried this and it worked for me.
Put your product tag like this:
Product Id="*" Name="Something" Language="1033" Version="1.0.0.0" Manufacturer="Someone" UpgradeCode="43ab28d7-6681-4a05-a6b5-f980733aeeed"
Product Id should be set to * so that every time you build your project, it takes different id.
Nest a MajorUpgrade tag inside your Package element which looks like:
MajorUpgrade AllowDowngrades="no" DowngradeErrorMessage="A newer version of [ProductName] is already installed." AllowSameVersionUpgrades="yes" /
So, every time you update your version(or your version is same, not less than current version), it reinstalls your product by removing the previous files and installing the product files.
It will not downgrade your product.
Just put this element under the Product element:
<MajorUpgrade AllowDowngrades="yes" />
More info in this HowTo