Multiple instances in Add/Remove program Wix - 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.

Related

Uninstall different product at install and major upgrade

Two different products have different UpgradeCodes and exist in two different setups (ProductA.msi and ProductB.msi). Both have version N.
Now ProductB is merged into ProductA version N+1. That is, ProductB's files will be provided by the installer of ProductA, and to the install location of ProductA.
A user that installs ProductA version N+1 would not like ProductB to be installed any more (it could even cause problems). So when ProductA is installed/upgraded to version N+1, ProductB (any version) should be removed. How can I accomplish this in the setup of ProductA?
It's similar to this question, but that is for removing a different product at uninstall rather than at install/upgrade. Wix - uninstall different product
WiX Sample: Here is a technical sample of doing as Bob Arnson describes: Adding entries to MSI UpgradeTable to remove related products. Make sure you leave this entry in your setup for future releases. It needs to persist there as people can skip a few version when upgrading?
Inline Sample: Please see link above for full sample.
<!-- Older Product Line 1: Upgrade Code -->
<Upgrade Id="{11111111-1111-1111-1111-000000000000}">
<UpgradeVersion Property="PRODUCTLINE1" IncludeMinimum="yes" Minimum="0.0.0" />
</Upgrade>
Debugging Major Upgrades: WIX does not uninstall older version - an ad-hoc list of causes for major upgrade failure.
Component Referencing: Merging setups can cause some component reference errors. I assume you are aware. This could manifest as missing files after installation or "some malfunction" during upgrade scenarios. Faulty registration, stranded files, you name it - just mentioning.
Component GUIDs: Here is some background information on component referencing and component GUIDs: Change my component GUID in wix?
As a rule of thumb: If you install the old files to a new location with new component GUIDs you should be fine. Things to check: shared files, COM servers, anything unsual in terms of machine-scope registration, services, COM Interop, COM+, etc... Many setups are simple, others are not.
Custom Actions: Migrating any custom actions can cause serious problems - especially during upgrade scenarios with complex sequencing and conditioning for when the actions actually run and not.
Add ProductB's upgrade code to a new Upgrade element in ProductA. Then when installing ProductA N+1, the upgrade will remove both ProductA N and ProductB.

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 - 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)?

Force uninstalling before installing any version with wix installer

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.