Doing Major Upgrade in Wix creates 2 entries in Add/Remove Programs - wix

I've followed the official Major Upgrade guide and I seem to be missing something.
Here is my MCVE:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Codepage="1252" Language="1033" Manufacturer="Bla Corporation"
Name="Bla" UpgradeCode="PUT-GUID-HERE" Version="31.00.0000">
<Package Comments="Contact: Refael Sheinker, refael.sheinker#bla.com." Description="Bla"
InstallerVersion="500"
Compressed="yes"
InstallScope="perMachine"
Keywords="Installer,MSI,Database" Languages="1033" Manufacturer="Bla Corporation" Platform="x64" />
<Media Id="1" Cabinet="my_application.cab" EmbedCab="yes" />
<MajorUpgrade AllowDowngrades="no"
AllowSameVersionUpgrades="no"
Disallow="no"
IgnoreRemoveFailure="no"
MigrateFeatures="yes"
Schedule="afterInstallInitialize"
DowngradeErrorMessage="A later version of [ProductName] is already installed" />
<Property Id="WIXUI_INSTALLDIR" Value="APPLICATIONROOTDIRECTORY" />
<UIRef Id="WixUI_InstallDir" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="PROGRAMFILESSUBDIR" Name="Bla">
<Directory Id="APPLICATIONROOTDIRECTORY" Name="BlaInternal" />
</Directory>
</Directory>
</Directory>
<DirectoryRef Id="APPLICATIONROOTDIRECTORY">
<Component Id="tenlira.ini" Guid="*">
<File Id="tenlira.ini" Source="..\ConfigurationFile\x64\tenlira.ini" KeyPath="yes" />
</Component>
</DirectoryRef>
<Feature Id="MainApplication" Title="TenLira" Level="1">
<ComponentRef Id="tenlira.ini" />
</Feature>
</Product>
</Wix>
All it does is simply installing a single file as an example. So far, so good. Now, all I do is add another Component and File and off course the corresponding ComponentRef in Feature. I specifically leave the Version as is: 31.00.0000. What I expected is that the new installer will not perform a Major Upgrade, but it does. Why? Also, there is now 2 entries in Add/Remove Programs.
Please help me find out what am I missing here. Thanks. Refael.
UPDATE:
Posting the question got me to reread the documentation again and I discovered that the AllowSameVersionUpgrades thingy in the MajorUpgrade element should be set to yes. This time there is only one entree in the Add/Remove Programs, but it still performs Major Upgrade. Why?

UPDATE: Here is a list to help debug failing major upgrades by identifying the most common problems: Common causes of failed major upgrades
Major Upgrade - "The Old, Manual Way"
I guess you are hitting an oddity that may not be handled entirely as expected by the WiX MajorUpgrade element by combining the auto-generated product GUID, the AllowSameVersionUpgrades set to yes and keeping the version number the same.
I can't see any obvious way to set the MinInclusive attribute in WiX's MajorUpgrade element - I could be mistaken, there might be a way I am unaware of. For what it is worth, I am not too keen on allowing "same version upgrades".
However, you could try to "use the old way" to author the Upgrade table using the "older elements" Upgrade and UpgradeVersion. The MajorUpgrade element is essentially a "convenience" feature to set up your major upgrades easily, and I believe it works for most users. Bob Arnson has a blog explaining the introduction of the MajorUpgrade element. This blog also shows a sample of how to do things "manually" with the "older elements" Upgrade and UpgradeVersion (do check it out).
I made a quick mock-up that might do what you want, it is just a "rough draft" - can't make any guarantees. I use preprocessor defines to set some variables that can be referenced in the WiX source file - as a C++ developer this is a piece of cake for you so I won't waste time explaining it - the source should make sense:
<?define MyProductVersion = "31.00.0000" ?>
<?define MyProductCode = "PUT-GUID-HERE" ?>
<?define MyUpgradeCode = "PUT-GUID-HERE" ?>
<!--Recommendation: set a path variable that you can redirect at will to a new release folder (new build output folder): -->
<!-- <?define MyBasePath = "C:\Projects\MyApp\Release\31.00.0000\" ?> -->
<!-- SAMPLE:
<Component Win64="yes" Feature="MainApplication">
<File Source="$(var.MyBasePath)\myapp.exe" />
</Component> -->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="$(var.MyProductCode)" Codepage="1252" Language="1033" Manufacturer="Bla Corporation"
Name="Bla" UpgradeCode="$(var.MyUpgradeCode)" Version="$(var.MyProductVersion)">
<Package Comments="Contact: Refael Sheinker, refael.sheinker#bla.com." Description="Bla"
InstallerVersion="500"
Compressed="yes"
InstallScope="perMachine"
Keywords="Installer,MSI,Database" Languages="1033" Manufacturer="Bla Corporation" Platform="x64" />
<Media Id="1" Cabinet="my_application.cab" EmbedCab="yes" />
<!-- 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>
<!-- Major Upgrade: Schedule RemoveExistingProducts -->
<InstallExecuteSequence>
<!-- Potential scheduling (after): InstallValidate, InstallInitialize, InstallExecute, InstallExecuteAgain, InstallFinalize -->
<RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>
<!--Launch Condition: Abort setup if higher version found-->
<Condition Message="!(loc.NewerVersionDetected)">
NOT DOWNGRADE_DETECTED
</Condition>
<Property Id="WIXUI_INSTALLDIR" Value="APPLICATIONROOTDIRECTORY" />
<UIRef Id="WixUI_InstallDir" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="PROGRAMFILESSUBDIR" Name="Bla">
<Directory Id="APPLICATIONROOTDIRECTORY" Name="BlaInternal" />
</Directory>
</Directory>
</Directory>
<DirectoryRef Id="APPLICATIONROOTDIRECTORY">
<Component Id="Test.ini" Guid="PUT-GUID-HERE" Win64="yes" Feature="MainApplication">
<CreateFolder Directory="APPLICATIONROOTDIRECTORY" />
<IniFile Id="SomeSetting" Action="addLine" Directory="APPLICATIONROOTDIRECTORY" Key="Setting1" Name="Test.ini" Section="MySection" Value="Some Setting" />
<IniFile Id="OtherSetting" Action="addLine" Directory="APPLICATIONROOTDIRECTORY" Key="Setting2" Name="Test.ini" Section="MySection" Value="Other Setting" />
</Component>
</DirectoryRef>
<Feature Id="MainApplication" Title="TenLira" Level="1">
<!--<ComponentRef Id="tenlira.ini" />-->
</Feature>
</Product>
</Wix>
Now the !(loc.NewerVersionDetected) has to be explained. This is a localized string (for delivering your setup in different languages). To use it, right click your WiX project in Visual Studio and go: Add New Item... => Localization File => Add. As the localization file is added, your output MSI will also now go into a en-us folder under your main output location (Debug or Release).
In the localization file, add:
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="NewerVersionDetected">A later version of [ProductName] is already installed.</String>
</WixLocalization>
And you should now be able to add new strings to this file and easily translate your whole setup using such language files.
Also add the WiX GUI extension. Right click "References". Add Reference... => Browse to WixUIExtension.dll => Double click this file, and press OK. Normal folder to find the file is: C:\Program Files (x86)\WiX Toolset v3.11\bin.
INI-Files
I just want to mention that INI files should ideally be installed via the IniFile table (entries are treated as atomic key-value pairs allowing advanced merging of keys and values for existing INI files), and not via the File table (the file is treated as a regular file either overwriting the whole existing file or leaving it in place - not enforcing any new values). The WiX element corresponding to the MSI IniFile table is naturally the IniFile element.
An ad-hoc sample:
<Component Id="Test.ini" Guid="PUT-GUID-HERE" Win64="yes" Feature="MainApplication">
<CreateFolder Directory="APPLICATIONROOTDIRECTORY" />
<IniFile Id="SomeSetting" Action="addLine" Directory="APPLICATIONROOTDIRECTORY" Key="Setting1" Name="Test.ini" Section="MySection" Value="Some Setting" />
<IniFile Id="OtherSetting" Action="addLine" Directory="APPLICATIONROOTDIRECTORY" Key="Setting2" Name="Test.ini" Section="MySection" Value="Other Setting" />
</Component>
Links:
Adding entries to MSI UpgradeTable to remove related products

It does a major upgrade because both MSIs have the same UpgradeCode and you have now specified AllowSameVersionUpgrades, so it does the upgrade where it didn't before.
Your build generates a new ProductCode every time, so each MSI is a new product, so you will get it installed twice if it doesn't do an upgrade and once if it does. You may have some assumption about the way upgrades work that you haven't spelled out.

I had the same problem where Version is same, but the Id is different creating multiple entries in Add/Remove programs.
My simple fix was to set AllowSameVersionUpgrades="yes".
<MajorUpgrade AllowSameVersionUpgrades="yes" DowngradeErrorMessage="A newer version of $(var.ServiceName) is already installed." />

Related

Simple Default Wix MSIX Project Throws a FgExcludeDarwinFeatures Error On Build

I'm testing out the MSIX features of the WiX framework. When I attempt to build I receive the following error:
light.exe(0,0): error LGHT0221: The definition for the
'FgExcludeDarwinFeatures' table's 'Feature_' column is a foreign key
relationship to the 'Feature' table's column number 1. The
modularization types of the two column definitions differ: one is
Column and the other is None. Change one of the modularization types
so that they match.
My setup:
Followed installation instructions from: https://www.firegiant.com/wix/wep-documentation/getting-started
Created a default wix setup project in visual studio 2019. Included FgMsixExtension.wixext.dll, included the fgmsix.xsd property on Wix element.
I'm running toolset v3.11.2.4516 (latest). Expansion Pack v3.11.476 - 2020-12-22 (latest)
Project compiles fine without the MSIX line, and the inclusion of the FgMsixExtension.wixext
Any ideas what I am missing?
Also does anyone have a working WiX msix example I can also compare to?
Just in case it is needed, here is a very quick edit of the default setup project from a wix template:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:fga="http://www.firegiant.com/schemas/v3/wxs/fgmsix.xsd">
<Product Id="*" Name="SetupProject3" Language="1033" Version="1.0.0.0" Manufacturer="test1" UpgradeCode="77c4b832-ed73-4ba2-825c-7eee7837a8f4">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<fga:Msix Id="testy" Publisher="CN=test1" Target="desktop" />
<!--<fga:Application Id="MyApp" ExecutableFile="prodFile" />-->
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Media Id="1" Cabinet="test.cab" EmbedCab="yes" />
<Feature Id="ProductFeature" Title="SetupProject3" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="SetupProject3" />
</Directory>
</Directory>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<Component Id="ProductComponent">
<File Id="prodFile" Source="C:\Program Files (x86)\WiX Toolset v3.11\bin\FireGiant.LicensingTool.exe" />
</Component>
</ComponentGroup>
</Product>
</Wix>
Just finished a conversation with FireGiant Support. This was due to a bug:
The dev team published the fix in v3.11.479. This should solve the issue you faced.
Let us know if you have any other questions or problems.
Happy packaging!
-- FireGiant Support
v3.11.479 released 01/15/2021

How to make certain a Wix installer will override (upgrade) an older version and won't allow a downgrade

I've tried most of the answers on the topic in this forum and other forums, but I still have this problem.
I want to update a bundle version and when I build and install the installer, it should upgrade a previous installation and not create two records in "Programs and Files".
I'm using the following code in Product.wxs.
<Product Id="*" Name="SetupProject1" Language="1033" Version="1.0.0.0" Manufacturer="miro" UpgradeCode="5ba49b49-25c4-47c0-82da-12bf5310af58">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade AllowDowngrades="no" AllowSameVersionUpgrades="yes" IgnoreRemoveFailure="no" DowngradeErrorMessage="loc.NewerVersionInstalled" Schedule="afterInstallInitialize"/>
<MediaTemplate />
<Feature Id="ProductFeature" Title="SetupProject1" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="SetupProject1" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<Component Id="ProductComponent">
<File Id="file_Exefile" Source="..\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe">
</File>
</Component>
</ComponentGroup>
</Fragment>
I am even considering writing my own update logic based on the Installer Processes and their ProductVersion properties, but there are too many cases to consider.
Can you tell me what is wrong with this Product.wxs ,so I can fix it.
Thanks.
Best regards,
Evgeni Dyulgerov
There are several things that could be preventing a major upgrade. You appear to have the correct MajorUpgrade logic, but:
It would be better if you incremented your product version in the first three fields, that's more normal for a major upgrade.
It's not obvious that your current UpgradeCode is the same as the older product's, so check that it is.
If the previous product's install scope was perUser the major upgrade will not work because cross-context major upgrades aren't allowed by Windows Installer.
Do the install taking a verbose log and look at all occurrences of FindRelatedProducts. There will be more than one, but see if the one in the upgrade install finds a previously installed product.
You have to add an upgrade section to your product section.
<Upgrade Id='5ba49b49-25c4-47c0-82da-12bf5310af58'>
<UpgradeVersion OnlyDetect='no' Property='ISUPGRADE'
Minimum='0.0' IncludeMinimum='yes'
Maximum='1.0.0.0' IncludeMaximum='no' />
</Upgrade>
Checkout Upgrades and Modularization on Firegiant
Also the WiX Documentation chm (in your Start Menu) is very helpful.

WiX Bootstrapper

I am trying to create an installer for a simple .NET WPF C# app. I am using VS 2013, and WiX 3.10.2. Following the steps in the Wix Tutotial/ .NET/ Bootstrapping I have created a Boostrap.exe which chains .NET web installer and the app Setup.msi.
EDIT: My goal is to understand how to configure the WiX Bootstrap and Setup projects for small updates, minor upgrades, and major upgrades scenarios.
Out of the box, everything seems to work nice when I run a fresh install. However, when I run a fresh built Bootstrap.exe over an already existing installation a duplicate entry appears in the Apps & features and no file is changed in the app target location - contrary to the expectation that the same entry should remain in the Apps & features and the target location should be updated. EDIT: Looks like there may not be a way to change REINSTALLMODE?
If I add a Product Id and then change the version of the Setup (minor upgrade), the Bootstrap fails with User cancelled installation? The log file shows "Error 0x80070642: Failed to perform minor upgrade of MSI package." EDIT: Inside the MSI log a SecureRepair fails with error code 39439E438 (?) probably because the stored hash value does not match the current... but that should be expected in a minor upgrade MSI, right?
Are there recommended configurations between the Boostrapper and Setup WiX projects such that the small update, minor upgrade, and major upgrade use cases can be handled properly, or does the WiX Bootstrapper support ONLY major upgrades?
I will continue to investigate and I'll post updates to my findings;
Any hints are greatly appreciated,
Thanks!
Here are the source files which I barely changed from the WiX wizard generated code:
--- Product.wxs ---
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="SetupProject1 1.0.0.0" Language="1033" Version="1.0.0.0" Manufacturer="Acme" UpgradeCode="4c8a8cbf-e3d0-410c-8a8d-7e67eb4e7ff7">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perUser" InstallPrivileges="limited" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="SetupProject1" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="LocalAppDataFolder">
<Directory Id="AcmeFolder" Name="Acme">
<Directory Id="INSTALLFOLDER" Name="WpfApplication1" />
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="ProductComponent" Guid="8CA0B70F-39DA-4B4B-9104-46C58E26FCF4">
<CreateFolder/>
<RemoveFolder Id="RemoveAcmeFolder" Directory="AcmeFolder" On="uninstall"/>
<RemoveFolder Id="RemoveINSTALLFOLDER" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\Acme\WpfApplication1" Name="Version" Type="string" Value="[ProductVersion]" KeyPath="yes" />
<File Source="$(var.WpfApplication1.TargetPath)" KeyPath="no" />
</Component>
</ComponentGroup>
</Fragment>
--- Bundle.wxs ---
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<Bundle Name="Bootstrapper1 1.0.0.0" Version="1.0.0.0" Manufacturer="Acme" UpgradeCode="e1092cbb-9134-42fc-a9f2-652f95f361fd">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<MsiPackage Name="Acme Setup" SourceFile="$(var.SetupProject1.TargetPath)" Vital="yes" />
</Chain>
</Bundle>
If you change your executables, increase their version numbers. Windows Installer assumes files with the same versions are the same.
To upgrade an .msi package, increase its version number either as part of a major upgrade (typical) or minor upgrade.
To upgrade a bundle, increase its version number. By default, Burn keeps bundles with the same version installed.

WIX Installer upgrade

I am trying to create an MSI using WIX and I seem to have stumbled across a small issue that is confusing me a bit in regards to the upgrade. I have followed about 3 tutorials on the subject and each one gives me the same result. When I try to upgrade the application I get a generic
Another version of this product is already installed.
message. After looking around I saw that in order to successfully upgrade I need to specify a new Product GUID. This seemed odd to me because the main WiX website said that that is only needed for major installs. Since I wasn't getting much luck I decided to go with it. Lo and behold it successfully executed the installer, but when I checked in Add/Remove Programs I now had 2 copies of the application installed. This is driving me crazy. Please see the below .wxs and please show me my errors where applicable.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="PRODUCT-GUID-GOES-HERE-B86BCC79EEFD" Name="Sample Application" Language="1033" Version="$(var.ProductVersion)" Manufacturer="Sample Inc." UpgradeCode="$(var.UpgradeCode)">
<Package Id="*" Keywords="Installer" Platform="x64" InstallerVersion="200" InstallPrivileges="elevated" InstallScope="perMachine" Compressed="yes" />
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Minimum="$(var.ProductVersion)" IncludeMinimum="no" OnlyDetect="yes" Language="1033" Property="NEWPRODUCTFOUND" />
<UpgradeVersion Minimum="$(var.RTMProductVersion)" IncludeMinimum="no" Maximum="$(var.ProductVersion)" IncludeMaximum="no" Language="1033" Property="UPGRADEFOUND" />
</Upgrade>
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="Sample" Name="Sample">
<Directory Id="INSTALLLOCATION" Name="Sample Application">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<Component Id="SampleApplication" Guid="APPLICATION-GUID-GOES-HERE-c7247f5d1b42" Win64="yes">
<!-- TODO: Insert files, registry keys, and other resources here. -->
<File Id="SampleEXE" Name="Sample.exe" Source="Sample.exe" ProcessorArchitecture="x64" KeyPath="yes" />
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
<Feature Id="Complete" Title="sample64" Level="1">
<!-- TODO: Remove the comments around this ComponentRef element and the Component above in order to add resources to this installer. -->
<ComponentRef Id="SampleApplication" />
<!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. -->
<ComponentGroupRef Id="Product.Generated" />
</Feature>
<CustomAction Id="NoDowngrade" Error="A later version of [ProductName] is already installed." />
<InstallExecuteSequence>
<Custom Action="NoDowngrade" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
<RemoveExistingProducts After="InstallFinalize" />
</InstallExecuteSequence>
<InstallUISequence>
<Custom Action="NoDowngrade" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
</InstallUISequence>
</Product>
</Wix>
Thanks in advance for any help.
Set Product/#Id to "*" to get automatic product code changes and use the MajorUpgrade element. For more context, see my blog.

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