Force uninstalling before installing any version with wix installer - wix

Does anyone know:
How can I Force wix installer to uninstall any previous copy previously installed, whether minor or major before installing a new version of our setup.
If 1) can't be done when running a new minor/major setup, can I at least display a message saying that a previous version was detected and it should first be uninstalled and cancel the setup?
Thanks.
UPDATE:
I've added the following to my settings.wxi
<Upgrade Id="$(var.UpgradeCode)">
<!-- Populate NEWERPRODUCTFOUND if there is an installed
package with the same upgrade code
and version is > the version being installed -->
<UpgradeVersion
Minimum="$(var.CurrentVersion)"
IncludeMinimum="no"
OnlyDetect="yes"
Language="1033"
Property="NEWERPRODUCTFOUND" />
<!-- 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.CurrentVersion)"
IncludeMaximum="no"
Language="1033"
Property="PREVIOUSVERSIONSINSTALLED" />
</Upgrade>
I've defined the following in MyProduct.wxs
<?define CurrentVersion="5.0.0.18"?>
<?define FirstVersion="1.0.0.0"?>
<?define UpgradeCode="c1b1bfa0-9937-49eb-812c-5bac06eff858"?>
and finally, I've added this to my <InstallExecuteSequence>
<RemoveExistingProducts Before="InstallInitialize" />
But it still not removing the old version when I increase my version to 5.0.0.19.
Maybe I'm looking at this the wrong way, but in my "Add/Remove Programs" window, I see my setup listed as 5.0.0.18 and I see a second entry as 5.0.0.19
Should I be changing the upgrade code every time I change my version? I thought I had read that this should never be changed.
Any ideas?
Thanks.

I figured out the answer after a lot of googling!! Windows Installer doesn't take into account the 4 number of the version which is what I was using i.e. 5.0.0.18.
It only looks at the first 3 sets of number making the version number. Once I changed my version to 5.0.18.0 to 5.0.19.0, it worked immediately with the code posted in the question and it removed the previous version and installed the newer one over it.
Note that I've actually removed the above code and ended up using the MajorUpgrade instead as it was all I needed:
<MajorUpgrade
AllowDowngrades="no"
AllowSameVersionUpgrades="no"
IgnoreRemoveFailure="no"
DowngradeErrorMessage="loc.NewerVersionInstalled"
Schedule="afterInstallInitialize"/>
Hope this helps someone else!

Here is the documentation for the AllowSameVersionUpgrades attribute of the MajorUpgrade element. It contains pertinent information. The emphasis is mine.
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.
This is useful when two product versions differ only in the fourth
version field. MSI specifically ignores that field when comparing
product versions, so two products that differ only in the fourth
version field are the same product and need this attribute set to yes
to be detected.
Note that because MSI ignores the fourth product version field,
setting this attribute to yes also allows downgrades when the first
three product version fields are identical. For example, product
version 1.0.0.1 will "upgrade" 1.0.0.2998 because they're seen as the
same version (1.0.0). That could reintroduce serious bugs so the
safest choice is to change the first three version fields and omit
this attribute to get the default of no.
This attribute cannot be "yes" when AllowDowngrades is also "yes" --
AllowDowngrades already allows two products with the same version
number to upgrade each other.
Setting this attribute to yes is probably not what you want, though, because, according to the third paragraph, version 5.0.0.18 would be seen as an upgrade over version 5.0.0.19. Set this attribute to no and use the third product version field to only allow upgrades.

Related

Multiple instances in Add/Remove program Wix

I'm using WixSharp to build an installer.
Using Major Upgrade element works as excepted(upgrade and downgrade)
I don't want multiple instances to be installed.
I've copy msi file in two location in the PC,
so I have two files: a.msi and b.msi with same version and upgrade code and different ProductId
installing a.msi works as excepted(open gui with remove option)
installing b.msi didn't work as excepted(install the product instead of saying that this is installed)
In Add/Remove programs I have two entries with same version.
How can I to disable it?
you can do this in two ways.
You can make the ProductId the same so that Windows sees that you install the same thing instead of thinking you are installing two different components (ProductId) of the same softwaresuite (UpgradeCode). This will result in an errormessage that the product is already installed until you increase the version.
Or
You can configure an upgrade fragment.
<Upgrade Id='$(var.UpgradeCode)'>
<UpgradeVersion OnlyDetect='no' Property='ISUPGRADE'
Minimum='1.0' IncludeMinimum='yes'
Maximum='$(var.ProductVersion)' IncludeMaximum='yes' />
</Upgrade>
which will uninstall the existing version and install the currently running setup.

Adding entries to MSI UpgradeTable to remove related products

A WiX installer product node has an attribute UpgradeCode. It is used to refer to previous versions of the same product. The value is stored in the UpgradeTable. The UpgradeTable is parsed by the FindRelatedProducts action.
The UpgradeCode allows to remove previous products with the same UpgradeCode. But the plan is to integrate several outdated legacy products to a combined single product. The UpgradeCode of this legacy product is known. I hope adding this code to the UpgardeTable will remove this legacy product too. This can be done by filling the UpgradeTable.
How can I add more entries in the UpgradeTable in a WiX setup?
Edit: What Syntax is required?
Is there a better way to remove products that are absolete after an upgrade?
Short Answer: You add several Upgrade Element entries in your WiX
source which will create several rows in the compiled MSI's Upgrade Table which then list products that are to be uninstalled during
installation (or that can abort your installation). You must be very careful about the options you specify for each product family to uninstall.
Major Upgrade Failure: Here is a list to help debug failing major upgrades by identifying the most common problems: Common causes of failed major upgrades.
Side-By-Side Installations: Be aware that an alternative to uninstalling older versions during a major upgrade, is to make your new version isolated enough to be able to co-exist with existing installations. Such isolation can be challenging, and is a whole other ballgame (prevent: fighting over file associations, incompatible COM server installations, incompatible runtimes, conflicting services, unexpected locks of configuration files and registry keys, etc...).
MajorUpgrade Element: Newer versions of WiX feature a "convenience feature" for major upgrade implementation in the form of the MajorUpgrade element. This elements simplifies the implementation of normal major upgrades.
Upgrade Element: In earlier versions of WiX more basic elements had to be used to implement major upgrades. This element is still available, and it is what you need to do more elaborate and fine-grained UpgradeTable configuration.
The differences between using these methods are very nicely illustrated by Wim Coenen here: Majorupgrade or Upgrade ID which is preferred for Major upgrade? I think that explanation is so good that I refuse to repeat it too much here :-). Give it a quick read please.
Major Upgrade Configuration Choices: The below is just a sample. The actual configuration of a major upgrade has to be carefully reasoned in each case:
Do you want to abort if higher versions are found?
From what product line?
What will the error message be?
Do you want to continue if an uninstall of an older version fails?
Do you want to allow lower versions to uninstall higher version? (please don't).
Do you want to allow the same version to uninstall itself and re-install?
You obviously have to plan for this and test in detail. Below is a mock-up. This combines the use of the MajorUpgrade Element and Upgrade elements. You can also rely solely on Upgrade elements to do things "manually" with more fine grained control:
<!-- Major upgrade - Your New Product Line, using the MajorUpgrade convenience element -->
<MajorUpgrade DowngradeErrorMessage="A later version of [ProductName] is already installed" />
<!-- Older Product Line 1: Upgrade Code -->
<Upgrade Id="{11111111-1111-1111-1111-000000000000}">
<UpgradeVersion Property="PRODUCTLINE1" IncludeMinimum="yes" Minimum="0.0.0" />
</Upgrade>
<!-- Older Product Line 2: Upgrade Code -->
<Upgrade Id="{22222222-2222-2222-2222-000000000000}">
<UpgradeVersion Property="PRODUCTLINE2" IncludeMinimum="yes" Minimum="0.0.0" />
</Upgrade>
<!-- Older Product Line 3: Upgrade Code -->
<Upgrade Id="{33333333-3333-3333-3333-000000000000}">
<UpgradeVersion Property="PRODUCTLINE3" IncludeMinimum="yes" Minimum="0.0.0" />
</Upgrade>
I would suggest you change the name of these PRODUCTLINE properties that is inherently understandable as a specific product line. In other words if you uninstall WiX3 you call it WIX3PRODUCTLINE etc... This is so the resulting log file is easier to comprehend.
Sample Upgrade Table:
The Attributes column of the Upgrade Table is important to control the behavior of the major upgrade. Continue on uninstall failure, etc...
And a list of free tools you can use to view a compiled MSI files (for whoever might find this answer): How can I compare the content of two (or more) MSI files?
UPDATE:
Unable to remove previous versions of MSI. Multiple entry's show up in control panel
WIX does not uninstall older version (potential causes of failed major upgrade)
Older Entries:
How can I find the Upgrade Code for an installed MSI file?
How can I find the product GUID of an installed MSI setup?
How To: Implement a Major Upgrade In Your Installer
Majorupgrade or Upgrade ID which is preferred for Major upgrade?
Major upgrades now easier than ever
Also want to send you to WiX expert Neil Sleightholm's site for some dated, but still good real-world samples:
WiX Script for Major Upgrades
LaunchConditions, FindRelatedProducts and Downgrades
Just add Upgrade and UpgradeVersion elements as required. That all just works. You might be using the MajorUpgrade element, and perhaps you're unaware of those other elements.

How to prevent Wix from installing an older version?

I have an application that we are switching over to a WiX installer. So far almost everything seems to be going well. The one problem I'm having is that if an older version is downloaded and attempted to install, it does so.
And that's a bit of a problem. If there is a newer version installed I don't want it to install the older version. I thought the problem was with the "Upgrade" component but I must admit I've hit a wall. How can I change it so that the older versions see there is a newer version already installed and not install it?
My test product is now in version 2.4 (the newest version we're trying to push out). It upgrades correctly to 2.4.1 or 2.5 or 3.0. But if I make a 3.0 version, and then run the msi for 2.4 it still adds it.
My upgrade component:
<Upgrade Id="PUT-GUID-HERE">
<UpgradeVersion Maximum="2.4" Property="PREVIOUSVERSIONSINSTALLED" />
<UpgradeVersion Minimum="1.0" Property="NEWERPRODUCTFOUND" OnlyDetect="yes" IncludeMinimum="no" />
</Upgrade>
Follow Up:
After following Steins suggestion I got an error like this
"Duplicate symbol 'WixAction:InstallExecuteSequence/RemoveExistingProducts' found"
After looking around in the Product.wxs file under the <InstallExecuteSequence>I had to delete <RemoveExistingProducts Sequence="6550" /> because that was the duplicate it was referring to. After doing that the installer worked and old versions can no longer be installed on top of new versions.
Packages of Futures Past: You can not change older versions of your package to detect newer ones. You need to build protection into your packages from the start. Packages need to be pre-cognitive. It's an industry problem.
Modern Times: The WiX elements you show above are "old-style". There is a new "convenience feature" described here: How do you detect installed product versions at each startup? It involves the "new" MajorUpgrade element. This new MajorUpgrade element features some auto-magic and I believe it adds the protection you describe by default (downgrade protection). Hence you can switch to using it. I would try that first. Let me inline the basic markup:
<MajorUpgrade Schedule="afterInstallInitialize"
DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit."
AllowDowngrades="no" AllowSameVersionUpgrades="no" />
In addition to removing the old-style upgrade elements, please also remember to delete any hard coded scheduling of the RemoveExistingProducts standard action. For example, remove this line (sequence number will likely be different, but same name):
<RemoveExistingProducts Sequence="6550" />
Decoupling: If you find that there is a high risk that people will run the older versions and mess with your newest application, you could set a new installation location and a new upgrade code for your latest version and install side-by-side to decouple your old and new products.
Side-By-Side: For this to work your product(s) must be capable of co-existing peacefully and not fight over file associations, per-machine registered COM servers, or other globally shared data that make the products interfere with each other. Whether this is possible or not depends on your application. A globally shared COM server can not be registered from two different locations - if you use normal registry registration (you can use manifest based reg-free COM though - though this is involved at times). There can be many challenges to overcome before your application supports side-by-side installation, or it could be rather trivial if your package is simple with no registry involvement.
Component GUIDs: You need to set new component GUIDs as well - for all components - in addition to the mentioned change of upgrade code in order to really shield the products from each other. If you use WiX auto-GUIDs this will happen auto-magically. The reason you need new component GUIDs is attempted explained here: Change my component GUID in wix? Essentially a GUID reference counts an absolute installation location, not a file per-se. You install to a new location, you need a new component GUID.

Wix - MSI Upgrade without removing older version

I would like to know if there is any way I can overwrite the old files using a newer version of the product. There are a few hundred files, so is there a better way to do this? As the upgrade is completely wiping out all files. I would like the upgrade MSI to overwrite the files.
My upgrade logic is as follows:
<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>
<CustomAction Id="PreventDowngrading" Error="Newer version already installed" />
<InstallUISequence>
<Custom Action="PreventDowngrading" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
</InstallUISequence>
<InstallExecuteSequence>
<Custom Action="PreventDowngrading" After="FindRelatedProducts">NEWPRODUCTFOUND</Custom>
<RemoveExistingProducts After="InstallFinalize" />
<InstallExecute After="RemoveExistingProducts" />
</InstallExecuteSequence>
I will need to write this quickly, please bear with me, but here goes:
Component GUIDs must stay the same between packages for files to update correctly, especially when you deploy via a patch. The key symptom of mismatching component GUIDs is exactly missing files after the deployment is complete (and patches that never work).
Set up a proper major upgrade as explained by PhilDW, and keep the component GUIDs consistent between releases and follow the component creation rules, and your upgrade should work correctly (and your patches too).
Note that you can leave the component GUIDs out of the WiX source file and allow them to be auto-generated rather than hard coded, and you will still get consistent GUIDs. Auto-generation of GUIDs will calculate a stable GUID (please read the linked question, the accepted answer along with all its comments) that remains stable between releases unless you rename or move the file in question - this requires a new component GUID, and here is why (this also explains why auto-generating stable GUIDs is possible). Auto-GUID generation will detect when a new GUID is required.
I am not up to speed on harvesting via heat.exe, but I think it allows the component GUIDs to be auto-generated rather than hard coded. Just change your script or automation process to set component GUIDs to auto-generate (this uses a * instead of a GUID in the component tag). Please read this entire answer with all answers and comments as well: Syntax for guids in WIX?
Important! A patch is just a delivery method for an MSI upgrade that is already working as a full package. Don't waste any time generating patches until you have verified that the full, updated MSI package upgrades the previous version correctly. You will just waste time if you do - the patch will never work if the full update doesn't work. It can't.
Is the first version of your product live? If it is not I would suggest starting over from scratch and use auto-generated GUIDs. If your previous version is live and you have hard coded component GUIDs you either need to match the existing component GUIDs in your first version with the component GUIDs in the updated version, OR you must put RemoveExistingProducts early in the InstallExecuteSequence as suggested by zett42 to allow the old version to fully uninstall before the new version is installed. This will prevent the previous error in component referencing to affect the major upgrade and no files should be missing after the upgrade. Patching will not be possible in this approach at all since component referencing isn't correct. This makes both minor and major upgrade patching fail - both require 100% component referencing to work properly.
This has already become long. If this all sounds Greek to you, please read up on the linked stackoverflow answers and get your head around MSI component creation best practice and component referencing in general. See MSDN as well for this. I will check back and see how you get on, and perhaps clean up this answer a little bit once I know what isn't clear and where you are at.

WiX - not executing custom action during update

I have two custom actions (immediate and deferrend). I would like to skipping actions during upgrade.
I tried:
<Product Id="*" Name="$(var.ProductName)" Language="1033" Version="$(var.Version)"
Manufacturer="$(var.Manufacturer)" UpgradeCode="{GUID}">
<MajorUpgrade DowngradeErrorMessage="Newer version is already installed." />
<Custom Action='CAa' After='InstallInitialize'>NOT Installed AND NOT PATCH</Custom>
and:
<Custom Action='CAa' After='InstallInitialize'>NOT Installed AND NOT UPGRADINGPRODUCTCODE</Custom>
Currently, actions starts during the update.
When you're doing a major upgrade with WiX MajorUpgrade the WIX_UPGRADE_DETECTED is set - see:
http://wixtoolset.org/documentation/manual/v3/xsd/wix/majorupgrade.html
so that is what you use in the upgrade install to detect that there is an older product installed. In other words it means that the new incoming install has detected an older version that is being upgraded.
UPGRADINGPRODUCTCODE is not the one to use. This property is set in the old product being upgraded and uninstalled so it knows the difference between being uninstalled and being upgraded, as the docs here say:
https://msdn.microsoft.com/en-us/library/aa372380(v=vs.85).aspx
"An application determines whether it is being removed by an upgrade or the Add or Remove Programs by checking UPGRADINGPRODUCTCODE."
Its value is the ProductCode of the incoming upgrade that is causing it to be removed.
These conditions are fiddly to get right - there are many options and modes for the InstallExecuteSequence (first time install, major upgrade install, minor upgrade install, maintenance install, uninstall, major upgrade uninstall sequence, patching, auto repair etc...). As I wrote in the comment above, you can try this PDF from Flexera.
No guarantees, but here is a proposal. You can try if this is what you want by showing message boxes from your CA (I can't test this using this lousy thin client, so it is a bit risky to try to answer without having done my own testing - please check carefully yourself):
Not Installed AND NOT PATCH AND NOT UPGRADINGPRODUCTCODE AND NOT REMOVE=~"ALL").
(NOT Installed) = run during first time installation
(NOT PATCH) = don't run during patching
(NOT UPGRADINGPRODUCTCODE) = don't run during a major upgrade uninstall
(NOT REMOVE=~"ALL") = don't run on uninstall
"Reference style table":
How to add a WiX custom action that happens only on uninstall (via MSI)?