With Wix Toolset is there a way with MajorUpgrade to set a minimum version - wix

We have been using the MajorUpgrade element in wix 3.11.1.2318, and our installer is not upgrading properly. It is not removing files and is leaving an extra entry in add/remove programs. During our build we switch Version="0.0.0.0" with the current version.
Below is a reduced sample to show our usage:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" >
<Product Id="*" Name="My Product" Language="1033" Version="0.0.0.0" Manufacturer="MyCompany"
UpgradeCode="{B55B9CB0-BA28-4BB3-834B-6075AD5D45E4}">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<UIRef Id="WixUI_ErrorProgressText" />
<!-- Specify UI -->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALL_FOLDER" />
<Property Id="RestoreFiles" Value="INSTALL_FOLDER" />
<MajorUpgrade AllowDowngrades="no" AllowSameVersionUpgrades="yes" DowngradeErrorMessage="!(loc.NewerVersionInstalled)" />
</Wix>
I looked at the Upgrade table in our msi, one entry had the MinVersion set to the version we had built and with no max version.
Another entry had the MaxVersion set to the version we had just built, and with no min version.
I thought that with the MinVersion set to our current version we would not be able to remove the files, so I looked
at the Upgrade element and replaced the MajorUpgrade element.
<!--
<MajorUpgrade AllowDowngrades="no" AllowSameVersionUpgrades="yes" DowngradeErrorMessage="!(loc.NewerVersionInstalled)" />
-->
<Upgrade Id="{B55B9CB0-BA28-4BB3-834B-6075AD5D45E4}">
<UpgradeVersion Minimum="1.0.0"
IncludeMinimum="yes"
OnlyDetect="no"
Maximum="0.0.0.0"
IncludeMaximum="no"
Property="OLDVERSIONFOUND" />
</Upgrade>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>
This did remove the older files, but left the second add/remove programs entry.
Is there a way with MajorUpgrade to set a minimum version?
Should I stay with Upgrade if there is no method to set minimum version?
What might be causing the second entry?

Logging: Please make sure to create a proper verbose log file for better clues to what is going on.
Major Upgrades: Some previous answers:
Here is a list of common causes of failed major upgrades (please skim the list first)
The use of both legacy and modern constructs to implement major upgrades.
Annotated WiX source showing old style major upgrades constructs in use
The upgrade settings you describe sound normal for WiX. I assume your build process successfully replaces the placeholder 0.0.0.0 (you search for that and replace it I presume). You could also use WiX variables and pass the value in, but that is another story.
Dangling Version?: Are you sure you don't have a dangling version in Add / Remove that isn't removed because it was a test version or something like that? Try generating a list of installed packages. Previous link is for a script which creates a small HTML report, you can try this simpler script to create output in *.csv format (which you can import to Excel and sort by name column to find duplicates easily). Try to install on a clean virtual to make sure. Just need to verify that this is not the case - one of those things that can be left unverified and be the cause.
Upgrade Table: Below is a sample upgrade table. Notice that the first entry is for the real major upgrade. It will detect all lower versions than the max version specified. You don't need to upgrade if your version is already installed. Hence we don't need max to be higher than the current version we install. In fact if the version you try to install you are supposed to go into "maintenance mode" - which shows a list of features you have installed and whatever features you have not installed.
The second row is to prevent overwriting a higher, existing installed version with a lower version than the setup you are running.

Related

For Wix Toolset and UpgradeVersion tag is Property ever reset

We have the code below for our Product.wxs.
When the installer is run we can see afterward that BackupFiles custom action runs, but RestoreFiles does not run as shown in the log file:
"Skipping action: RestoreFiles (condition is false)"
Why does BackupFiles, with same condition, run and RestoreFiles not run?
Has the OLDVERSIONFOUND been changed?
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension" >
<Product Id="*" Name="My Product" Language="1033" Version="0.0.0.0" Manufacturer="MyCompany"
UpgradeCode="{B55B9CB0-BA28-4BB3-834B-6075AD5D45E4}">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<UIRef Id="WixUI_ErrorProgressText" />
<!-- Specify UI -->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALL_FOLDER" />
<Property Id="RestoreFiles" Value="INSTALL_FOLDER" />
<Upgrade Id="{B55B9CB0-BA28-4BB3-834B-6075AD5D45E4}">
<UpgradeVersion Minimum="1.0.0"
IncludeMinimum="yes"
OnlyDetect="no"
Maximum="0.0.0.0"
IncludeMaximum="no"
Property="OLDVERSIONFOUND" />
</Upgrade>
<InstallExecuteSequence>
<Custom Action="BackupFiles" After="InstallValidate" >OLDVERSIONFOUND</Custom>
<Custom Action="SetRestoreFiles" Before="RestoreFiles" />
<Custom Action="RestoreFiles" After="InstallFiles" >OLDVERSIONFOUND></Custom>
<RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>
</Wix>
Custom actions like these are not really recommended. They can be quite complicated to get right. See links towards the bottom on "settings preservation".
The short version is that settings files should never be installed, but created by the application from defaults or templates (then the setup will never interfere with them), or you can cloud all settings and retrieve on launch from a database. See here, section "cloud-style approaches".
Major Upgrades - Uninstall & Install: There is an important weirdness with major upgrades. You have to remember that you kick off the new installer, and then it will kick of the old installer's uninstall sequence as part of its own operation. Hence a major upgrade will run the uninstall sequence of your old setup and the install sequence of your new setup (potentially in different orders based on configuration of the major upgrade settings).
Counter-Intuitive Effects: This combined "install / uninstall" approach affects logic, conditioning, sequencing and also property values a great deal - and some changes are very counter-intuitive. In addition to two different versions running "at the same time" (or during the same operation), you must also keep in mind that the each installation / uninstallation sequence runs in two different modes: immediate (building execution script) and deferred (executing script executing). With poor conditioning the same custom action could run several times unexpectedly (including in the GUI sequence of the launched setup). Confusing. Debug using message boxes as described towards the bottom here.
Detailed Explanation: This complexity and the phenomenon of property values seemingly changing during installation is attempted explained in detail here: Run Wix Custom action only during uninstall and not during Major upgrade - please read that answer (dual source and all). I will look back later, it is too late for me to run tests tonight.
Throwing in some further links:
On settings preservation
Overview on settings preservation
"Property Debugger" - on how to test property values
"Property Debugger" - another version

WIX: Prevent only CERTAIN older versions from being updated

We have some product, that uses WIX as installer technology. Upgrade handling in the installer is handled by he MajorUpgrade element
<Wix>
<Product Id="..." Name="..." Language="..."
Version="..." Manufacturer="..."
UpgradeCode="...">
...
<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" AllowSameVersionUpgrades="yes" />
</Product>
</Wix>
As you can see, we supported upgrades from all older version until now, however we have to change this a bit, so that only versions newer than a certain version can be upgraded, while older versions receive an error message and upgrade fails.
From what I've researched, this should be doable with the Upgrade element (as described in https://www.firegiant.com/wix/tutorial/upgrades-and-modularization/checking-for-oldies/)
My question now:
is it possible/recommended to mix MajorUpgrade and Upgrade elements?
is there a better way for achieving this?
Update
Thanks for the replies and answers, my used solution is the following:
<Wix>
<Product Id="..." Name="..." Language="..."
Version="..." Manufacturer="..."
UpgradeCode="My_upgrade_code">
...
<InstallExecuteSequence>
...
<Custom Action='UpdateFromVersionNotSupported' After='FindRelatedProducts'>UNSUPPORTEDUPDATEVERSIONFOUND</Custom>
...
</InstallExecuteSequence>
<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" AllowSameVersionUpgrades="yes" />
<Upgrade Id='My_upgrade_code'>
<UpgradeVersion OnlyDetect='yes' Property='UNSUPPORTEDUPDATEVERSIONFOUND' Maximum='Oldes_version_where_update_is_allowed' IncludeMaximum='no' />
</Upgrade>
<CustomAction Id='UpdateFromVersionNotSupported' Error='Updates are only supported from version ?? or later' />
</Product>
</Wix>
There should be a few approaches:
New UpgradeCode: Changing the upgrade code would decouple the older versions and the newer ones? You can add both upgrade codes to the upgrade table and handle them differently. See the image below and this answer:
Versioning: You can also use version matching to upgrade only certain MSI versions. Upgrade Table documentation. In other words set the max and min versions to target with each upgrade table entry. You can keep adding rows to handle different versions differently. Something like this (just a rough mock-up):
WiX Constructs: You can mix and match the modern WiX convencience element
with the older and more flexible elements. See this answer.
Side-By-Side MSI: Note that if you want to install the same MSI twice on the same computer interference will result unless you do work to isolate the instances (COM servers, file associations, services, etc... - anything machine-wide and interference capable). The worst of it is generally things registered system-wide accessed via the registry (unless it is multi-instance capable). More technical information here. Virtualization can help? See the links for details.
You'll need to use the Upgrade element.
https://wixtoolset.org/documentation/manual/v3/xsd/wix/upgrade.html
https://wixtoolset.org/documentation/manual/v3/xsd/wix/upgradeversion.html
You need to write 2 rules. One that allows an upgrade for version X or higher. This can be your standard MajorUpgrade element. And another that detects a version <X and triggers a Condition that displays a message informing the user to uninstall first and blocks installation.

msi upgrade when I change the ProductVersion to a different format fails

I have the following problem and I'm trying to understand what is happening. I have this code:
...
<Product Name="My Service"
Id="*"
UpgradeCode="$(var.UpgradeCode)"
Language="$(var.Language)"
Codepage="$(var.CodePage)"
Version="$(var.ProductVersion)"
Manufacturer="$(var.Manufacturer)">
<Package Id="*"
Keywords="Installer"
Description="My Service Installer"
Comments="Service Installer"
Manufacturer="$(var.Manufacturer)"
InstallerVersion="300"
Languages="$(var.Language)"
Compressed="yes"
SummaryCodepage="$(var.CodePage)" />
<Upgrade Id="$(var.UpgradeCode)">
<!-- Populate NEWERVERSIONDETECTED if there is an installed
package with the same upgrade code
and version is > the version being installed -->
<UpgradeVersion Minimum="$(var.ProductVersion)"
IncludeMinimum="no"
OnlyDetect="no"
Property="NEWERVERSIONDETECTED" />
<!-- Populate UPGRADEFOUND if there is an installed
package with the same upgrade code
and the version is between the earliest version defined
and the version being installed -->
<UpgradeVersion Minimum="$(var.FirstVersion)"
IncludeMinimum="yes"
Maximum="$(var.ProductVersion)"
IncludeMaximum="no"
Property="PREVIOUSVERSIONSINSTALLED" />
</Upgrade>
<Condition Message="A newer version is already installed.">NOT NEWERVERSIONDETECTED</Condition>
<InstallExecuteSequence>
<RemoveExistingProducts Before="InstallInitialize" />
</InstallExecuteSequence>
<!-- Step 1: Define the directory structure -->
...
<!-- Step 2: Add files to your installer package -->
...
<!-- Step 3: Tell WiX to install the files -->
...
ProductVersion and FirstVersion has the x.x.x format. Because the msi contains only 3 files I prefer to uninstall everything and put the new files in place (like a major upgrade).
Here is what it's happening:
FirstVersion is defined as "0.0.1"; I build twice my project (to generate two msi with ProductVersion "0.0.2" for the first build and with "0.0.3" for the second). When I install 0.0.3 on top of 0.0.2 everything is going smoothly. In Add/Remove Programs I see the new version installed, "My Service" is up&running in Local Services, in Program Files I see my folder containing the new files.
If I build the project with the ProductVersion 2.0.2 and 2.0.3 (same steps as the previous ones), when I install 2.0.3 on top of 2.0.2, no error pops-up, the installation finishes successfully (at least Event Viewer says so) but my folder in Program Files doesn't exist, My Service is unknown in Local Services (it will not start). The only thing looking good is in Add/Remove programs which shows me the new version 2.0.3 is installed. And another strange thing is the fact that I can uninstall my application from Add/Remove Programs successfully. No error!
So why for 0.0.x format as ProductVersion upgrading is working fine, but
not for 2.0.x?
I tried to log the output of msiexec during the upgrading, but it is too
complicated for me.
PS: do not recommend another way of implementing upgrade. I need to stick
to this code because I'm using msitools which has a lot of limitations.
The versions is right, you haven't made any mistake there.
Without a verbose log your chances to find the problem are quite small. It is not hard at all. Follow the link above and you will find examples on multiple methods to generate a log and share it with us or try to read it be yourself.

upgrade version using WIX

I've made an installer using the WIX toolset (3.10). I'd like to enable upgrades but I can't make it work. Every time I run the msi it installs another version.
I can't figure out what's wrong. can anyone advise?
<Product Id="*"
Name="$(var.PRODUCTNAME)"
Language="1033"
Version="$(var.PRODUCTVERSION)"
Manufacturer="Manufacturer"
UpgradeCode="UPGRADE_CODE"
>
<Package InstallerVersion="200"
Compressed="yes"
InstallScope="perMachine" />
<MajorUpgrade Schedule="afterInstallInitialize"
AllowDowngrades="no"
AllowSameVersionUpgrades="no"
DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
AllowSameVersionUpgrades="yes" will probably fix this. When you test upgrades you need to either always update the version (one of the first 3 parts) between installers or just allow the same version upgrades.
from the wix website
When set to no (the default), installing a product with the same version and upgrade code (but different product code) is allowed and treated by MSI as two products. When set to yes, WiX sets the msidbUpgradeAttributesVersionMaxInclusive attribute, which tells MSI to treat a product with the same version as a major upgrade.
So your install thinks these two installs are separate things even though they share the same upgrade code which is why you get 2 copies in your add remove programs list.
I use a GUID for the UpgradeCode (I suppose that's what UPGRADE_CODE means).
You can also set the REINSTALLMODE property to change your reinstallation behavior.
It could look like this:
<SetProperty Id="REINSTALLMODE" Value="amus" After="FindRelatedProducts">Installed AND REMOVE<>"ALL"</SetProperty>
Just be aware that a will reinstall your product regardless of the installed version. But you can look up which characters you need for your installer.
For Value="amus" you can refer to the Microsoft documentation here
In addition to your MajorUpgrade property it is crucial that your UpgradeCode does not change for future versions. Might that be the problem?

WiX creating duplicate records in ARP when I change the version number

My WiX installer does not uninstall previous version record in ARP when I change the version number. It installs the updated files, but I end up with duplicate records in ARP. Does this have something to do with minor versus major upgrades? The beginning of my WiX installer file is as follows:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="Blah" Language="1033" Version="1.0.0.6" Manufacturer="Blah Inc." UpgradeCode="c6044fe4-e07a-4dd0-9540-cc77b4430466">
<Package Id ="*" Keywords="Installer" Description="Blah Installer" Manufacturer="Blah Inc." InstallerVersion="200" Compressed="yes" InstallScope="perMachine" InstallPrivileges="elevated" />
<Property Id="OLDVERSION" Secure="yes" />
<Upgrade Id="7BDF86F7-C6A8-4112-9DA6-FDFB6864AE66">
<UpgradeVersion OnlyDetect="no" Minimum="1.0.0.0" Maximum="99.0.0.0" Property="OLDVERSION" IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>
<InstallExecuteSequence>
<RemoveExistingProducts Overridable="no" After="InstallInitialize" />
</InstallExecuteSequence>
Couple of things to check:
Is the Upgrade ID same for both MSI's? The MSI wont know that there is a related product installed unless the upgrade GUID's are same.
Looks like you have updated only the last digit of the version number? if your version 1 uses Version value 1.0.1.0, then version 2 should have a Version value of 1.0.2.0 or higher (1.0.1.1 will not work here).
From Wix3.5, there is a new element called MAJORUPGRADE MajorUpgrade which consolidates the lines which you have written and makes things easier. Can you make use of that and see if it works? Here is a link to Bob Arnsons blog introducing "MajorUpgrade" MajorUpgrade
Check this link for more details: How to implement major upgrade
Your Upgrade Code must generally be stable across versions to identify the products in question as related. They seem to differ in your code.
Furthermore you must implement a major upgrade to ensure that the old product version is uninstalled before the new one is installed. Otherwise you will get multiple installations showing up in ARP.
For good measure always uppercase your GUIDs, though I believe WIX will do this for you on compile. And make sure you uninstall all versions of your application before you try anything else.