249

At work we use WiX for building installation packages. We want that installation of product X would result in uninstall of the previous version of that product on that machine.

I've read on several places on the Internet about a major upgrade but couldn't get it to work. Can anyone please specify the exact steps that I need to take to add uninstall previous version feature to WiX?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dror Helper
  • 30,292
  • 15
  • 80
  • 129

12 Answers12

233

Finally I found a solution - I'm posting it here for other people who might have the same problem (all 5 of you):

  • Change the product ID to *
  • Under product add The following:

    <Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
    <Upgrade Id="YOUR_GUID">  
       <UpgradeVersion
          Minimum="1.0.0.0" Maximum="99.0.0.0"
          Property="PREVIOUSVERSIONSINSTALLED"
          IncludeMinimum="yes" IncludeMaximum="no" />
    </Upgrade> 
    
  • Under InstallExecuteSequence add:

    <RemoveExistingProducts Before="InstallInitialize" /> 
    

From now on whenever I install the product it removed previous installed versions.

Note: replace upgrade Id with your own GUID

ssingh3
  • 125
  • 1
  • 8
Dror Helper
  • 30,292
  • 15
  • 80
  • 129
  • Seems this question is much more popular then I thought – Dror Helper Feb 16 '09 at 13:50
  • 166
    yes, learning WiX is like trying to figure out the obscure incantations that someone decided 'made sense' to perform a simple action. Kind of like UNIX. – mmr Mar 25 '09 at 00:44
  • Hm, I suspect that I shouldn't use that particular GUID in the "Upgrade Id=", but will have to match it so something else. But what? – Anthony Apr 06 '09 at 21:27
  • Also you may have to tweak the UpgradeVersion Min and max - e.g. If your current version is less than 1.0 – Anthony Apr 06 '09 at 21:29
  • 6
    Also, what exactly does "Change the product ID to *" do? Does it generate a new product Id each time? Are there consequences to your product not having a fixed Id any more? - it sounds like overkill. – Anthony Apr 07 '09 at 08:58
  • 1
    @Anthony - yes using * will cause it to generate a new product ID each time. I found that for the "automatic upgrade" to work I need a new product Id for each version and this is the simplest way to do so – Dror Helper Apr 07 '09 at 10:50
  • 1
    We need to know the ID so generate (manually) a new ID for each public release. Using the same ID for all internal betas. Works OK but you can't autoupgrade between betas which is OK for us – saschabeaumont Apr 07 '09 at 10:56
  • 10
    @Antony, @Dror Helper: I'm pretty sure you should not be using "*" to generate a new GUID here. The GUID inside (Upgrade Id="") should be hard-coded and fixed, and it should match the GUID in your (Product UpgradeCode="") attribute. – Jonathan Hartley Sep 30 '09 at 11:32
  • 2
    By which I mean, don't use "*" in the upgrade Id, but do, of course use it in the product Id as Dror intended. – Jonathan Hartley Sep 30 '09 at 12:39
  • 3
    note that this will remove _any_ version installed, even if it is newer than the one you are trying to install – Lucas Dec 02 '09 at 21:38
  • 38
    I think you should probably edit your example there to NOT have an actual GUID. I'm sure people will copy-and-paste that and use it verbatim. Maybe use "YOUR-PRODUCT'S-UPGRADECODE-GUID-HERE"? – Brown Feb 05 '10 at 19:54
  • 12
    There is bug in your example. MSI's `ProductVersion` only supports three version fields; therefore the fourth field will not be compared at all. See the note under VersionMin and VersionMax in http://msdn.microsoft.com/en-us/library/aa372379(VS.85).aspx – Sridhar Ratnakumar Aug 26 '10 at 18:50
  • For wix2, Product ID should be `"????????-????-????-????-????????????"` instead of `"*"` – Sridhar Ratnakumar Aug 26 '10 at 19:09
  • 2
    Although the upgrade seems to work using the method above, in "Add Remove Programs" I still see the old version (and of course the new one). Any ideas why that happens and how I can really delete the old version? – Florin Sabau Nov 02 '10 at 08:58
  • Using this technique, do I still need to change the UpgradeCode between releases? – Florin Sabau Nov 02 '10 at 09:05
  • This helped me too, turns out the PREVIOUSVERSIONSINSTALLED is really important, even though nothing appears to be using the property... – Hakanai Jun 02 '11 at 05:57
  • 2
    I've done exactly what was suggested, but this isn't working for me. If I run my newer install, it simply ignores the existing installation and installs a fresh copy. What kind of things might I be missing? – Jonathan Aug 04 '11 at 06:01
  • 2
    I don't seem to have an InstallExecuteSequence element... (scratching head). – jpierson Apr 24 '12 at 20:40
  • @jpierson Are you sure you're placing InstallExecuteSequence in the right parent? I've made that mistake a few times already – Disillusioned Apr 30 '12 at 12:22
  • 6
    Why isn't there a "DontCareJustCopyTheFiles" element? – ActiveTrayPrntrTagDataStrDrvr Dec 17 '13 at 15:56
  • @DrorHelper Is it possible to remove(uninstall) more than one product using wix during the installation of msi created by wix. Plese look into my SO question and guide me http://stackoverflow.com/questions/26863294/uninstall-a-application-during-installation-not-working – user2725407 Nov 16 '14 at 14:53
  • I'm not sure, I haven't done WIX in a while - I think you should write a question instead of a comment so that other users can help you. – Dror Helper Nov 18 '14 at 07:11
  • I assure you @mmr, packaging on Linux is a *lot* simpler. – Aaron C. de Bruyn Sep 20 '15 at 18:36
  • Please note that this solution won't work if WIX installer has multiple project files and if you are trying to build the project with msbuild. – Jayee Jul 28 '16 at 06:27
  • @mmr I wish there was an option to bookmark comments. WiX is driving me nuts for several days now and all I want to implement is a simple upgrade scenario. – Andreas May 17 '22 at 05:05
218

In the newest versions (from the 3.5.1315.0 beta), you can use the MajorUpgrade element instead of using your own.

For example, we use this code to do automatic upgrades. It prevents downgrades, giving a localised error message, and also prevents upgrading an already existing identical version (i.e. only lower versions are upgraded):

<MajorUpgrade
    AllowDowngrades="no" DowngradeErrorMessage="!(loc.NewerVersionInstalled)"
    AllowSameVersionUpgrades="no"
    />
Rowland Shaw
  • 37,700
  • 14
  • 97
  • 166
Ant
  • 5,150
  • 2
  • 33
  • 41
  • 8
    Bob Arnson's [blog post](http://www.joyofsetup.com/2010/01/16/major-upgrades-now-easier-than-ever/) about this provides a lot of nice information. – Dave Andersen Jul 26 '12 at 18:15
  • 20
    Note: Not documented anywhere, but the "``" element must be placed *after* ``. Otherwise, `candle` gives the following error: "error CNDL0107 : Schema validation failed with the following error at line 1, column 473: The element 'Product' in namespace 'http://schemas.microsoft.com/wix/2006/wi' has invalid child element 'MajorUpgrade' in namespace 'http://schemas.microsoft.com/wix/2006/wi'. List of possible elements expected: 'Package'.". – Rob W Jan 31 '13 at 11:39
  • 23
    +1 This answer needs to receive as many upvotes as possible; it's very tempting to go with an answer that has 5x the upvotes, but uses older approaches. – Lynn Crumbling Feb 20 '14 at 16:59
  • 1
    Good point. I've added an example so that people don't ignore it just because it doesn't have one! – Ant Feb 21 '14 at 13:22
  • 6
    Just want to point out you don't need to specify `AllowDowngrades` or `AllowSameVersionUpgrades`. They default to no already. – Luminous May 15 '15 at 14:17
  • True. I wanted it to be obvious to anyone else reading my particular piece of code, but of course that won't be the case for everyone! – Ant May 20 '15 at 07:22
  • 1
    I've changed it to the accepted answer since it's better than my original findings – Dror Helper Sep 29 '15 at 09:59
  • Hopefully this won't resurrect an old thread, but I feel a couple of additional things could be mentioned for creating a "newer" version: 1) You need to increment one of the first three digits of the "Product Version" attribute. 2) Change the GUID in "Product UpgradeCode". 3) Put an actual GUID in "Package Id" attribute (as opposed to the recommended asterisk), and keep that constant across versions. WIX coughs up a huge warning for the GUID, but it won't work as an upgrade otherwise. – Chris Parker Dec 24 '18 at 19:46
  • 2
    My previous comment is wrong - ignore it. What I described does not complain when installing, it doesn't upgrade like I thought. Put an asterisk in "Product Id". Put an actual GUID in "Product UpgradeCode" - and NEVER change this. Put an asterisk in "Package Id". Finally, when you increment the numbers in "Product Version", it'll do an actual update. – Chris Parker Dec 24 '18 at 21:57
  • Tried this and got "another version of this product is already installed" – AriesConnolly Jul 15 '20 at 12:16
  • Same as AriesConnolly, another version of this product is already installed error – sushi7777 Sep 02 '20 at 13:12
  • My understanding is that you get that error when you've recompiled your setup program without increasing the version number. You can set the `AllowSameVersionUpgrades` attribute to `yes`, but that comes with its own problems... – Ant Sep 10 '20 at 11:16
91

The following is the sort of syntax I use for major upgrades:

<Product Id="*" UpgradeCode="PUT-GUID-HERE" Version="$(var.ProductVersion)">
 <Upgrade Id="PUT-GUID-HERE">
    <UpgradeVersion OnlyDetect="yes" Minimum="$(var.ProductVersion)" Property="NEWERVERSIONDETECTED" IncludeMinimum="no" />
    <UpgradeVersion OnlyDetect="no" Maximum="$(var.ProductVersion)" Property="OLDERVERSIONBEINGUPGRADED" IncludeMaximum="no" />
</Upgrade>

<InstallExecuteSequence>
    <RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>

As @Brian Gillespie noted there are other places to schedule the RemoveExistingProducts depending on desired optimizations. Note the PUT-GUID-HERE must be identical.

Rob Mensching
  • 33,834
  • 5
  • 90
  • 130
  • 2
    I'm reading the "Upgrading and Patching" section in Nick Ramirez' book on Wix here, and he states that if you schedule RemoveExistingProducts after InstallInitialize, then you MUST also schedule ``. Your example does not have this - does that mean the book is wrong? – Wim Coenen Nov 19 '10 at 14:50
  • 3
    I never explicitly schedule InstallExecute. – Rob Mensching Nov 23 '10 at 03:43
  • Out of interest, what do you do for minor upgrades? – Richard Szalay Apr 14 '11 at 17:36
  • 1
    I don't. In WiX v3.6, Burn will make minor upgrades easy to execute but without Burn it requires manual interaction from the user (have to provide command-line options) that makes Minor Upgrades basically useless. :) – Rob Mensching May 01 '11 at 15:47
  • 1
    @RobMensching: how do you avoid the installation of an older version over a newer one? Your answer works for me (the only "major upgrade" example that I can get to compile at all with WiX v3.5.2519.0), but it's possible to install an older version (after that, I see both versions in "Add/Remove Programs"). – Christian Specht Nov 29 '11 at 21:47
  • 4
    Okay, I just found the [MajorUpgrade element](http://wix.sourceforge.net/manual-wix3/wix_xsd_majorupgrade.htm) in [this answer](http://stackoverflow.com/a/3575801/6884) which does exactly what I want, including preventing downgrades. – Christian Specht Nov 29 '11 at 22:08
  • @RobMensching Is it possible to remove(uninstall) more than one product using wix during the installation of msi created by wix.I am able to upgrade the previous version with new one using wix but i need to unintall other 2 appliction also during this upgrade. Plese look into my SO question and guide me http://stackoverflow.com/questions/26863294/uninstall-a-application-during-installation-not-working – user2725407 Nov 16 '14 at 15:00
40

The Upgrade element inside the Product element, combined with proper scheduling of the action will perform the uninstall you're after. Be sure to list the upgrade codes of all the products you want to remove.

<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<Upgrade Id="00000000-0000-0000-0000-000000000000">
  <UpgradeVersion Minimum="1.0.0.0" Maximum="1.0.5.0" Property="PREVIOUSVERSIONSINSTALLED" IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>

Note that, if you're careful with your builds, you can prevent people from accidentally installing an older version of your product over a newer one. That's what the Maximum field is for. When we build installers, we set UpgradeVersion Maximum to the version being built, but IncludeMaximum="no" to prevent this scenario.

You have choices regarding the scheduling of RemoveExistingProducts. I prefer scheduling it after InstallFinalize (rather than after InstallInitialize as others have recommended):

<InstallExecuteSequence>
  <RemoveExistingProducts After="InstallFinalize"></RemoveExistingProducts>
</InstallExecuteSequence>

This leaves the previous version of the product installed until after the new files and registry keys are copied. This lets me migrate data from the old version to the new (for example, you've switched storage of user preferences from the registry to an XML file, but you want to be polite and migrate their settings). This migration is done in a deferred custom action just before InstallFinalize.

Another benefit is efficiency: if there are unchanged files, Windows Installer doesn't bother copying them again when you schedule after InstallFinalize. If you schedule after InstallInitialize, the previous version is completely removed first, and then the new version is installed. This results in unnecessary deletion and recopying of files.

For other scheduling options, see the RemoveExistingProducts help topic in MSDN. This week, the link is: http://msdn.microsoft.com/en-us/library/aa371197.aspx

Brian Gillespie
  • 3,213
  • 5
  • 27
  • 37
  • 2
    @Brian Gillespie: what does "...if there are unchanged files..." mean? What is the criteria for Windows Installer to decide when to replace a file, AssemblyVersion, AssemblyFileVersion, file size,...? – donttellya May 21 '14 at 09:01
  • 2
    @donttellya +1 learnt this the hard way. `RemoveExistingProducts` was scheduled to after `InstallFinalize` and dlls were not being updated as assemblyVersion was unchanged but other fields like AssemblyProduct were. I dont want to be at the mercy of the file comparison routine - i just want the previous app GONE – wal Feb 18 '15 at 01:25
16

You might be better asking this on the WiX-users mailing list.

WiX is best used with a firm understanding of what Windows Installer is doing. You might consider getting "The Definitive Guide to Windows Installer".

The action that removes an existing product is the RemoveExistingProducts action. Because the consequences of what it does depends on where it's scheduled - namely, whether a failure causes the old product to be reinstalled, and whether unchanged files are copied again - you have to schedule it yourself.

RemoveExistingProducts processes <Upgrade> elements in the current installation, matching the @Id attribute to the UpgradeCode (specified in the <Product> element) of all the installed products on the system. The UpgradeCode defines a family of related products. Any products which have this UpgradeCode, whose versions fall into the range specified, and where the UpgradeVersion/@OnlyDetect attribute is no (or is omitted), will be removed.

The documentation for RemoveExistingProducts mentions setting the UPGRADINGPRODUCTCODE property. It means that the uninstall process for the product being removed receives that property, whose value is the Product/@Id for the product being installed.

If your original installation did not include an UpgradeCode, you will not be able to use this feature.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Mike Dimmick
  • 9,662
  • 2
  • 23
  • 48
  • 25
    No doubt Mike knows exactly what he is talking about, all due respect, but it makes me sigh with despair to contemplate cluttering my mind with a firm understanding of what the Windows Installer is doing. Before I know it, I'll be doing Java and .NET consulting jobs to Enterprise clients out in the godawful tech centre towns, out beyond the ring-road, filling my TPS reports and wondering why life seems so empty. I think my next project might install with NSIS, which for all its faults, like a preposterous assembly-like language, it didn't make me understand what Windows Installer is doing. – Jonathan Hartley Sep 30 '09 at 12:54
  • 2
    @Tartley - go with InnoSetup, that'll save you the assembly-like language :) Make sure you grab IStool too, it helps a lot. Also -- agreed that for simple installs all this is way too complicated, but I think they really need this complexity for installing something like SQL Server 2008... – Roman Starkov Nov 17 '09 at 10:32
11

I used this site to help me understand the basics about WiX Upgrade:

http://wix.tramontana.co.hu/tutorial/upgrades-and-modularization

Afterwards I created a sample Installer, (installed a test file), then created the Upgrade installer (installed 2 sample test files). This will give you a basic understanding of how the mechanism works.

And as Mike said in the book from Apress, "The Definitive Guide to Windows Installer", it will help you out to understand, but it is not written using WiX.

Another site that was pretty helpful was this one:

http://www.wixwiki.com/index.php?title=Main_Page

Rob W
  • 341,306
  • 83
  • 791
  • 678
CheGueVerra
  • 7,849
  • 4
  • 37
  • 49
  • The example on the page does not work as expected http://wix.tramontana.co.hu/tutorial/upgrades-and-modularization/checking-for-oldies . I played with it. It is even possible to downgrade when page states that it will be prohibited – sergtk Jun 10 '12 at 01:49
11

I read the WiX documentation, downloaded examples, but I still had plenty of problems with upgrades. Minor upgrades don't execute uninstall of the previous products despite of possibility to specify those uninstall. I spent more that a day for investigations and found that WiX 3.5 intoduced a new tag for upgrades. Here is the usage:

<MajorUpgrade Schedule="afterInstallInitialize"
        DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit." 
        AllowDowngrades="no" />

But the main reason of problems was that documentation says to use the "REINSTALL=ALL REINSTALLMODE=vomus" parameters for minor and small upgrades, but it doesn't say that those parameters are FORBIDDEN for major upgrades - they simply stop working. So you shouldn't use them with major upgrades.

Marek R
  • 32,568
  • 6
  • 55
  • 140
Sasha
  • 8,537
  • 4
  • 49
  • 76
7

I would suggest having a look at Alex Shevchuk's tutorial. He explains "major upgrade" through WiX with a good hands-on example at From MSI to WiX, Part 8 - Major Upgrade.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Faraz
  • 189
  • 3
  • 9
7

One important thing I missed from the tutorials for a while (stolen from http://www.tramontana.co.hu/wix/lesson4.php) which resulted in the "Another version of this product is already installed" errors:

*Small updates mean small changes to one or a few files where the change doesn't warrant changing the product version (major.minor.build). You don't have to change the Product GUID, either. Note that you always have to change the Package GUID when you create a new .msi file that is different from the previous ones in any respect. The Installer keeps track of your installed programs and finds them when the user wants to change or remove the installation using these GUIDs. Using the same GUID for different packages will confuse the Installer.

Minor upgrades denote changes where the product version will already change. Modify the Version attribute of the Product tag. The product will remain the same, so you don't need to change the Product GUID but, of course, get a new Package GUID.

Major upgrades denote significant changes like going from one full version to another. Change everything: Version attribute, Product and Package GUIDs.

Daniel Morritt
  • 1,787
  • 17
  • 25
  • 3
    Package:Id type:AutogenGuid description: The package code GUID for a product or merge module. When compiling a product, this attribute should not be set in order to allow the package code to be generated for each build. When compiling a merge module, this attribute must be set to the modularization guid. ---- so we don't need pay attention on the package id, right? – Cooper.Wu Oct 18 '11 at 04:27
  • Your link is dead – Laurent Mesguen Feb 22 '17 at 15:30
5

I'm using the latest version of WiX (3.0) and couldn't get the above working. But this did work:

<Product Id="*" UpgradeCode="PUT-GUID-HERE" ... >

<Upgrade Id="PUT-GUID-HERE">
  <UpgradeVersion OnlyDetect="no" Property="PREVIOUSFOUND"
     Minimum="1.0.0.0"  IncludeMinimum="yes"
     Maximum="99.0.0.0" IncludeMaximum="no" />
</Upgrade>

Note that PUT-GUID-HERE should be the same as the GUID that you have defined in the UpgradeCode property of the Product.

Merill Fernando
  • 177
  • 1
  • 4
3

Below worked for me.

<Product Id="*" Name="XXXInstaller" Language="1033" Version="1.0.0.0" 
    Manufacturer="XXXX" UpgradeCode="YOUR_GUID_HERE">
<Package InstallerVersion="xxx" Compressed="yes"/>
<Upgrade Id="YOUR_GUID_HERE">
    <UpgradeVersion Property="REMOVINGTHEOLDVERSION" Minimum="1.0.0.0" 
        RemoveFeatures="ALL" />
</Upgrade>
<InstallExecuteSequence>
    <RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>

Please make sure that the UpgradeCode in Product is matching to Id in Upgrade.

zed
  • 2,298
  • 4
  • 27
  • 44
NishantJ
  • 61
  • 3
1

This is what worked for me, even with major DOWN grade:

<Wix ...>
  <Product ...>
    <Property Id="REINSTALLMODE" Value="amus" />
    <MajorUpgrade AllowDowngrades="yes" />
Gian Marco
  • 22,140
  • 8
  • 55
  • 44