WiX3 major upgrade not working - wix

I have a major upgrade that I am trying to do, but it just doesn't work. It simply installs the new program along side the old one. They are in different directories (as I changed the directory structure with the new version) so there are no conflicts, but the old one NEEDS to be erased in order for my product to function properly.
<Property Id="UPGRADE_NEEDED" Secure="yes" />
<Property Id="SAME_OR_NEWER_VERSION" Secure="yes" />
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallFinalize" />
</InstallExecuteSequence>
<Upgrade Id="{PUT-YOUR-GUID-HERE}">
<UpgradeVersion Minimum="5.1.3" OnlyDetect="yes" IncludeMinimum="yes" Property="SAME_OR_NEWER_VERSION" />
<UpgradeVersion Minimum="5.1" Maximum="5.1.3" Language="1033" Property="UPGRADE_NEEDED" MigrateFeatures="yes" IncludeMinimum="yes" />
That is my upgrade elements (with GUID removed of course). If anyone can find where the problem lies I would greatly appreciate it.

There are some general rules for an upgrade to be working:
Old and new products must have identical UpgradeCode values and
different ProductCode values.
Old and new products must have identical values for
InstallAllUsers [i.e. a per-machine
installation cannot upgrade a per-user
installation and vice-versa.]
New product's setup Version (the setup project, nothing to do with file
versions) must be higher.
All setup versions (again, not file versions) must be 1.0 or greater.
Further details how to correctly implement an upgrade using WiX can be found in this thread:
How to implement WiX installer upgrade?

Related

WiX: How to not launch install if previous version not found?

How can I make the install require a previous version to be installed?
Is that not the purpose of Upgrade element? I cannot get it to work as expected.
The upgrade is happy to launch with or without previous 1.2.3 version installed.
Here is what I did:
Opened version 1.2.3 of the original MSI in Wix Edit
Replaced a single DLL with an updated DLL
Updated version to 1.2.4
Updated Product Id
UpgradeCode did * not * changed
Added Upgrade element after the last Property element
Code Sample:
<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<Upgrade Id="{59BF7F9E-FF46-45D5-8050-F1477466A661}">
<UpgradeVersion Minimum="1.2.3" Maximum="1.2.3" IncludeMinimum="yes"
IncludeMaximum="yes" Property="PREVIOUSVERSIONSINSTALLED" />
</Upgrade>
<RemoveExistingProducts Sequence="1525" />
Thanks in advance,
-Ed
I have never heard of such a design. Normally you make a setup capable of installing fresh and to update any previous versions on the system. See this thread: How to implement WiX installer upgrade?

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.

Dealing with Changed Upgrade Code in WiX, where old installer allowed both per-user and per-machine

I have a product that used to ship with a .vdproj installer. In the most recent version, I shipped a beta with a completely redone installer using WiX (as part of the move to Visual Studio 2012, which no longer supports .vdproj). Unfortunately, at the time I didn't know that the upgrade code was supposed to be consistent across copies, and already shipped one beta installer with a different upgrade code.
I would like my installer to automatically remove previous versions built with the .vdproj installer, as well as the version that was shipped as a beta copy. This is where I've gotten so far:
<Product Id="{A4CBA9F9-D86B-400C-BD23-996B4367931A}" Name="Foo Viewer" Language="1033" Version="6.0.1.0" Manufacturer="Foo Corporation" UpgradeCode="43e024b8-b3ea-40a3-a854-2af83f207f0f">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MediaTemplate EmbedCab="yes" />
<Feature Id="FOOVIEWERFeature" Title="Foo Viewer" Level="1" Description="The Foo Viewer GUI and CLI binaries." AllowAdvertise="no" Absent="disallow" Display="expand">
<!-- Stuff -->
</Feature>
<PropertyRef Id="NETFRAMEWORK40CLIENT" />
<Condition Message="Foo Viewer requires the .NET Framework 4.0 Client Profile or higher to run.">Installed OR NETFRAMEWORK40CLIENT</Condition>
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<UIRef Id="FooViewerInstallerUI" />
<UIRef Id="WixUI_ErrorProgressText" />
<Icon Id="FooViewerIcon" SourceFile="../FooViewer.ico" />
<Property Id="ARPPRODUCTICON" Value="FooViewerIcon" />
<!-- I got this upgrade code by opening one of the old .vdproj MSIs in Orca -->
<Upgrade Id="{80539F30-8176-4DCC-A102-ED32A34A91CB}">
<UpgradeVersion OnlyDetect="no"
Minimum="0.0.0.0"
IncludeMinimum="yes"
MigrateFeatures="no"
IgnoreRemoveFailure="no"
Property="UPGRADE_VDPROJ_FOOVIEWER"
/>
</Upgrade>
<Upgrade Id="{43e024b8-b3ea-40a3-a854-2af83f207f0f}">
<!-- Foo Viewer 6.0.0.0 (Beta) shipped with a version 5.3.0.0 in the installer. -->
<UpgradeVersion OnlyDetect="no"
Minimum="5.3.0.0"
Maximum="5.3.0.0"
IncludeMinimum="yes"
IncludeMaximum="yes"
MigrateFeatures="yes"
IgnoreRemoveFailure="no"
Property="UPGRADE_WIX_FOOVIEWER"
/>
<!-- Detect newer versions -->
<UpgradeVersion OnlyDetect="yes"
Minimum="6.0.1.0"
IncludeMinimum="no"
Property="NEW_VERSION_FOUND"/>
</Upgrade>
<Condition Message="A newer version of Foo Corporation Foo Viewer is already installed.">
Installed OR NOT NEW_VERSION_FOUND
</Condition>
<InstallExecuteSequence>
<RemoveExistingProducts Before="InstallInitialize" />
</InstallExecuteSequence>
</Product>
However, despite putting in a <upgrade> element for the old installer's upgrade code, the old version isn't getting removed. As a result the new copy tries to install on top of the old copy, and then neither version works any longer.
The detection of the beta copy, and of newer versions, works correctly (the <Upgrade with GUID {43e024b8-b3ea-40a3-a854-2af83f207f0f} ). The beta version gets uninstalled, and if I generate a "newer" installer, then the current installer correctly doesn't install. That is, the WiX installers have no problem detecting each other.
Is there something I did wrong here that won't let it detect the old .vdproj installed copies?
EDIT: I tool a log of the installation process when this happens, I get the following:
Action start 17:25:47: FindRelatedProducts.
MSI (c) (10:B8) [17:25:47:269]: FindRelatedProducts: current install is per-machine. Related install for product '{2024FF03-D6F2-4065-A22B-80252B2A66B6}' is per-user. Skipping...
Action ended 17:25:47: FindRelatedProducts. Return value 1.
which appears to be accurate. The old installer gave an option for "Per User" or "Per Machine", whereas the new installer always forces per machine. If I select "Everyone who uses this computer" in the old installer, then the new installer is able to detect it. I would like to detect either option if possible in the WiX.
I'm afraid you can't deal with 2 different existing installations at the same time in single installer. Moreover you shouldn't try to run uninstallation of another product (since your UpgradeCode and ProductCode are different, it is anoter product) because msi can't work with simultaneous installations.
What I would recommend is creating separate exe application (bootstrapper), which will run child uninstallation processes of previously installed products and then immediately run your product's installation (probably in full UI mode).
To uninstall the product with no user interaction, use the following command:
msiexec /x {ProductCode} /qn
I hope you know the ProductIds of the previously installed products. If not, you can find it, searching the registry:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\{ProductCode}\DisplayName
and HKEY_CURRENT_USER if application was installed for single user.
{ProductCode} mentioined in registry path is GUID which is your productCode. You should retrieve all nodes in "Uninstall" branch and find those which are your products checking the "DisplayName" attribute. I hope you know at least the name of the products installed =). And be careful not to delete all software on client's machine =)
Please note if you installed x86 application on x64 machine, you should search location
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{ProductCode}\DisplayName"
One more important notice: if your bootstrapper will be also x86 application, you should retrieve node without "Wow6432Node" node because it will be automatically inserted in the requested path. Wonderful world of registry keys on different platforms =).
Please ensure your bootstrapper will be run with admin permission or will ask permission elevation (it should contain security manifest).
One assumption about problem in your post: maybe you didn't change the ProductCode when changed the UpgradeCode? I'm not sure how it will behave, but it is definitely not a MajorUpgrade which automatically removes the previously installed product. For more details see Wix documentation on upgrades. So you might got Minor upgrade or patch which directly installs new components on top of the previously installed files. That definitely could break the application.

I have installed major upgrade successfully but it also allowing another previous version install in wix

I have installed major upgrade (say #206) successfully and included code as in (#206):
<Upgrade Id="$(var.ProductUpgradeCode)">
<UpgradeVersion Minimum="$(var.ProductVersion)" IncludeMinimum="no" OnlyDetect="yes" Language="1033" Property="NEWPRODUCTFOUND" />
<UpgradeVersion Minimum="1.0.0.178" IncludeMinimum="yes" Maximum="$(var.ProductVersion)" IncludeMaximum="no" Language="1033" Property="UPGRADEFOUND" />
</Upgrade>
Scenario is:
I have installed build #177 then upgraded to build #206. It is still allowed to install #177 which I want to prevent this downgrade.
From build #178 onward I have changed product GUID for major upgrade and which is working fine.
Please suggest how to prevent this. I don't want to downgrade build below 177. If I have done major upgrade on build no <= 177.
Your problem is the how the comparison of versions is done in MSI by default - 1.0.0.123 is treated the same as e.g. 1.0.0.33. You either have to increase your revision version to make the installer detect this as an older version or use a workaround.
You might for instance create a custom action to check against this very Revision version and place it e.g. before InstallValidate:
<CustomAction Id='MyVersionCheck' Return='check' (...) />
<InstallExecuteSequence>
<Custom Action='MyVersionCheck' Before='InstallValidate' />
</InstallExecuteSequence>
Some more information can be found in this article, for informations about how to create custom actions i'd recommend this blog entry as a starting point.

Windows installer deletes versioned file during product upgrade, instead of downgrading it

We use wix to create our setups. For upgrading, we use major upgrades as demonstrated in this answer by Rob Mensching. (In newer wix versions you can use the MajorUpgrade element.) This normally works well. The old product is removed, then the new product is installed.
However, apparently the above is not completely equivalent to manually uninstalling the old product and then manually installing the new product.
Consider for example the following scenario:
version 1.0 of our product is released, containing version 5.0 of a thirdparty dll
version 1.1 of our product is released, containing version 5.1 of the same thirdparty dll
version 1.2 of our product is released, downgrading to version 5.0 of the thirdparty dll again because we discovered that the new version introduced more problems than it solved.
Apparently with the wix upgrade logic linked above, the 3rdparty dll will disappear when upgrading from release 1.1 to 1.2. A repair is necessary to restore it.
Is there another way to upgrade, which would work for this scenario? I guess what I am looking for is upgrade logic which allows the downgrading of components, by behaving exactly as if one manually uninstalls the old product and then manually installs the new product.
We also encountered this problem where lower-versioned DLLs were not getting reinstalled on a major upgrade. I thought it was strange that the installer would decide which files to install based on the versioning of existing files, then completely uninstall everything, but still only install what what files had been determined to install before uninstalling the old product. This seems like it might be a bug in Windows Installer...
To fix this problem we moved the RemoveExistingProducts action above the CostFinalize action.
I know the documentation on MSDN recommends placing the RemoveExistingProducts afterInstallValidate, and I'm not sure if putting it before the InstallValidate action has any negative side effects for minor upgrades, but we have decided to only perform major upgrades for our products so this solution appears to work for us.
Behaviors like this generally have to do with the sequencing of RemoveExistingProducts. If it occurs late enough, Windows Installer will have figured out that there's a newer version of the .dll on the machine, so version 1.2 doesn't need to install it. However when the RemoveExistingProducts results in removing the .dll, nothing puts it back.
Things to try including changing the sequencing of RemoveExistingProducts, and lying about the version of the .dll in your 1.2 package (report a version number higher than the bad one). The downside of the latter is poor impacts on repairs or patching, as the .dll always looks out of date.
Try to schedule RemoveExistingProducts earlier, right after InstallValidate, and change the value of REINSTALLMODE property to amus. This way the old product will be completely removed before any files from the new product are copied, and a mode will force re-install of the files.
It's sub-optimal, but I fixed the same problem by renaming the third party dll and changing the GUID on the component node associated with it in the .wxs file.
Years later, this thread helped me in the right direction. An example for completeness with RemoveExisitingProducts moved before costing:
<Upgrade Id="UPGRADE-GUID-HERE">
<UpgradeVersion OnlyDetect="no" Property="UPGRADABLEFOUND"
Maximum="$(var.ProductVersion)" IncludeMaximum="yes" />
<UpgradeVersion OnlyDetect="yes" Property="NEWERFOUND"
Minimum="$(var.ProductVersion)" IncludeMinimum="no" />
</Upgrade>
<InstallExecuteSequence>
<Custom Action="NoDowngrade" After="FindRelatedProducts">NEWERFOUND</Custom>
<RemoveExistingProducts Before="CostInitialize" />
</InstallExecuteSequence>
<CustomAction Id="NoDowngrade" Error="A newer version of $(var.ProductName) is already installed." />
Here's my final solution based on the answer given by #Spacemani.
It produces MSI table entries (Upgrade, LaunchCondition etc.) similar to this
<MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeErrorMessage)" />
but gives you full control of the InstallExecuteSequence.
<!-- Product upgrade -->
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion OnlyDetect="no" Property="WIX_UPGRADE_DETECTED"
Maximum="$(var.ProductVersion)" IncludeMaximum="no" IncludeMinimum="no"
MigrateFeatures="yes" />
<UpgradeVersion OnlyDetect="yes" Property="WIX_DOWNGRADE_DETECTED"
Minimum="$(var.ProductVersion)" IncludeMinimum="no" />
</Upgrade>
<InstallExecuteSequence>
<RemoveExistingProducts Before="CostInitialize" />
</InstallExecuteSequence>
<Condition Message="!(loc.DowngradeErrorMessage)">NOT WIX_DOWNGRADE_DETECTED</Condition>
Note that you need to suppress ICE27 errors in your .wixproj file like this.
<PropertyGroup>
<SuppressIces>ICE27</SuppressIces>
</PropertyGroup>