I have a wix bundle which has say 4 MSIs - all with version 1.0.0 and Bundle version as 1.0.0. I install this on a windows machine and in the ARP I see the WiX bundle as 1.0.0.
Now I make some changes to only one of the MSIs, say B, and change the Bundle version to 1.1.0 and the changed MSI (B) version to 1.1.0. The rest of the MSIs (A, C, D) are still at 1.0.0.
Now when I run the bundle again, I expect that installation for A, C and D would be skipped and only B would be upgraded and the bundle will also be updated with version 1.1.0 in the ARP. But what I observe is that installation for all the packages (A,B,C,D) take place and not just B.
So is my expectation wrong or am I doing something wrong?
This is what I have in my bundle code
<Chain>
<MsiPackage Id=“A"
Cache="no”
Vital=“yes"
EnableFeatureSelection="no"
Permanent="no" Visible="no"
ForcePerMachine=“yes”
SourceFile = “<>”/>
<MsiPackage Id=“B"
Cache="no”
Vital=“yes"
EnableFeatureSelection="no"
Permanent="no" Visible="no"
ForcePerMachine=“yes”
SourceFile = “<>”/>
</Chain>
And this is what I have in my wxs for the individual MSIs. I change the version to 1.1.0 only for MSI B and keep the UpgradeCode same.
<Product Id="*" UpgradeCode="<GUID which is same across installations>"
Version="1.0.0" />
<MajorUpgrade DowngradeErrorMessage="New version is present."
I looked up many threads but generally they talk about upgrading all the MSIs, just not 1 MSI. Let me know if something is unclear and thanks in advance for your help.
Burn won't install a package if it's already installed. But if you rebuild a package with Product/#Id="*", the package identity changed (both product code and package code). So Burn installs what looks like a new package. If you want Burn to skip such a package, don't rebuild it.
Part of the majorUpgrade Element there is a AllowSameVersionUpgrades attribute, with default value no.
Meaning "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."
Check this attribute and see if it helps with your issue.
The best practice is to change the version to all msis and the bundle, this is done automatically part of the CI/CD pipeline of releasing the product.
Related
I have two products which I'm trying to write an installer for. Both products are wix bundles which both have a third product bundle as a requirement.
Ideally what I want to happen when you install one is:
If Product3 is not installed then it should be.
If Product3 is installed and installed version is higher or the same do nothing.
If Product3 is installed and installed version is lower then upgrade.
If uninstalling and product1 or 2 is still installed do not uninstall product3.
So far I was able to conquer some of these points but not all at the same time.
Originally I tried getting the installed version using a ProductSearch and using InstallCommand. However I ran into problems with uninstalling when doing side by side installs because the installcommand is more like "requested install state" and so if I don't want it to install when it detects the same version it actually starts uninstalling it.
I took a look at this similar answer:
How to avoid uninstalling previously installed ExePackage (redistributables) while installing a WiX Bundle?
which suggested using the provideskey and requires elements but I cannot find any useful documentation on them whatsoever. I tried experimenting with it but it doesn't seem to do anything at all.
I've looked at RelatedBundle but I'm not sure it's what I'm after. Seems more targeted at hotfixing systems.
I was hoping there was a way of doing this without having to resort to custom actions since that seems a bit extreme for what seems to be rather simple functionality.
After a lot of trial and error I figured out how to get the DependencyExtension working.
In the example below ProductC is a Wix Bundle executable. This bundle includes an MSI file. I use a productSearch to look for the upgrade code of that MSI file (NOT THE BUNDLE) to detect if it's already installed.
In your bundle file for project A and B:
<Wix xmlns:dep="http://schemas.microsoft.com/wix/DependencyExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle>
<util:ProductSearch Id="ProductCInstallSearch"
UpgradeCode="{ProductC_MSI_UpgradeCode_GUID}"
Variable="ProductCInstalled"
Result="state"/>
<dep:Requires Id="ProductCRequired" ProviderKey="ProductC"/>
<Chain>
<PackageGroupRef Id="ProductC_pkg"/>
</Chain>
</Bundle>
<Fragment Id="Required_Pkgs">
<PackageGroup Id="ProductC_Pkg">
<ExePackage Id="ProductC_Bundle"
Permanent="no"
DetectCondition="NOT ProductCInstalled = 2"
InstallCommand="/quiet"
UninstallCommand="/uninstall /quiet">
<dep:Provides Key="ProductC"
Version="0.0.0.0">
<dep:RequiresRef Id="ProductCRequired"/>
</dep:Provides>
</ExePackage>
</PackageGroup>
</Fragment>
</Wix>
Now you can install A and B in any arrangement and when uninstalling product C will only be removed when the last one is uninstalled.
I'm using wix Bundle to install chain of Msi's , When i'm trying to upgrade the older version is not uninstalling
please help me on doing below any of the scenarios
How can i uninstall the previous version before install the latest version
Always upgrade to the latest version, In My case it can be major release or minor release or patch release
There's more to it then just uninstalling. First of all let's take a look at your versioning. The bundle itself has version and each of msis has its own version. I hope that when there's time for upgrade you have to upgrade the entire bundle without checking each of the packages separately, it might make it a bit easier. So now, each of MSIs should have Product > Upgrade attribute set and have Upgrade node. The values should be the same. Bundle should have attribute UpgradeCode. This should be enough for you to uninstall the previous version and install a new one.
Now, if you want to show something in the UI, you can go to your bootstrapper application and subscribe to all kinds of Detect events. There are some related to upgrade.
Here's the MSI that support update:
<Product Id="*" Name="$(var.ProductName)" Language="1033" Version="1.0.0.5" Manufacturer="$(var.Manufacturer)" Upgrade="GUID_HERE">
<Package InstallerVersion="450" Compressed="yes" InstallScope="perMachine" />
<Upgrade Id="SAME_GUID_HERE"/>
And burn:
<Bundle Name="$(var.ProductName)"
Version="1.0.0.5"
Manufacturer="$(var.Manufacturer)"
UpgradeCode="ANOTHER_GUID"
So once you install packages with GUIDs inside, the next version will detect (using GUID) that product is installed already and will do an upgrade.
In this way I was able to block the appearance of multiple bootstrapper windows. Eventually, no programs appears and we only see Msi. https://stackoverflow.com/a/62262418/12267227
We are upgrading our WIX msi installer (not a bundle) with manual pre-requisites to a Managed custom Bootstrapped application Bundle. The boot strapped custom installer bundle exe works fine for fresh installs. But if we want to upgrade our older product which is just an msi, we are in trouble. This is what I am trying to do
Detect RelatedMsiFeatureHandler detects there is an older msi package installed.
I am handling the Plan events for individual packages and setting the states as desired. For ex: state = Present for install
I cannot to Apply(UpdateReplace) because I do not have an older Bundle,
The million dollar question is how do I upgrade this msi package?
Any help is appreciated.
Thanks
All I had to do was set the MsiProperty UPGRADE=1 in Bundle.wxs for the relevant Msi Package in the chain. This made sure that when the Bundle.exe is run the specific msi is upgraded BTW: this is the first version of Bundle for us. We had just an MSI before for installation.
<MsiPackage DisplayName="Installing Main Product" SourceFile="$(var.Path_Setup)" DisplayInternalUI="no" SuppressSignatureVerification="yes" >
***<MsiProperty Name="UPGRADE" Value="1"/>***
<MsiProperty Name="NAS_PATH" Value="[NasBackupPath]"/>
<MsiProperty Name="NAS_BAK_TIME" Value="[BackupTime]"/>
</MsiPackage>
</Chain>
Just in case if anyone having similar issue (WIX 3.10)
this statment under the installer's Product will resolve the issue. You must update the version of the product and product upgrade code must be same with previous install.
"AllowSameVersionUpgrades" = yes will make sure not to install same product side by side.
Im using WiX to install my .msi, I´m generating a WiX Bundle using the Bundle Element.
I try to not show the Bundle on "Add/Remove programs" so i set the properties of the Bundle element like this:
<Bundle Name="$(var.ProductName)" Version="!(bind.packageVersion.MSIPackage)"
Manufacturer="$(var.ProductManufacturer)" UpgradeCode="$(var.UpgradeCode)"
DisableRemove="yes" DisableModify="yes" DisableRepair="yes">
DisableRemove, DisableModify and DisableRepair to "yes" made the Bundle be hidden under "Add/Remove programs".
My problem is that when i Uninstall my application, the application is uninstalled correctly but the Bundle remains Hidden, so it cause some problems when i try to install other version of the App, for example the new Bundle detects that there are other Bundle installed and performs some versioning check and so on.
So my question is: is possible to when the application in uninstalled from the "Add/Remove programs" uninstall the Hidden Bundle as well?
To expand on Tom's answer, if you remove the Disables from your Bundle tag
<Bundle Name="$(var.ProductName)" Version="!(bind.packageVersion.MSIPackage)"
Manufacturer="$(var.ProductManufacturer)" UpgradeCode="$(var.UpgradeCode)">
You can modify your MsiPackage tag to hide the MSI from Add/Remove Programs
<MsiPackage
Id="YOUR-ID"
Vital="yes"
DisplayName="$(var.ProductName)"
SourceFile="$(var.Source.TargetPath)">
<MsiProperty Name="ARPSYSTEMCOMPONENT" Value="1"/>
</MsiPackage>
This will leave just one entry in Add/Remove Programs. Your Bundle will now handle the UI of the install and uninstall, and will correctly allow other versions of the bundle to be installed.
Well, you could use a custom action in the msi but don't.
You have inverted the designed relationship between bundles and packages. I suggest that you hide the package and show the bootstrapper in ARP.
The bootstrapper engine ("burn") is a package manager that collaborates with Windows Installer. Together they handle upgrades and uninstallation of packages. If, after understanding how it works, you don't want what it does then you may want a self-extractor instead of burn. (Some projects that do use burn are Visual Studio and WiX itself.)
Use -repair option when running the installer every time. It's a hack but it works. The problem is that the bundle uninstall is hidden, and when running uninstall you are only removing the package inside, not the bundle.
This causes the issue when you want to run the installation again after uninstalling the package inside. The installer thinks that the bundle is still installed. By using the -repair option (every time you install the bundle), you are telling it to either install the bundle if no bundle is present. or repair it if the package was removed.
-repair = repair (or install if not installed)
I have a very simple WiX project (version 3.7) that installs somes files (a .NET program version 6.0.0.0). I'm ready to release a new version 6.0.1.0 using the MajorUpgrade functionality in WiX.
I'm keeping the UpgradeCode the same in the Product element and I change the Version from 6.0.0.0 to 6.0.1.0
<Product Id="*" Name="MyApp" Version="6.0.1.0" Manufacturer="Me"
UpgradeCode="$(var.TheUpgradeCodeGUID)">
On a machine with 6.0.0.0 installed, I run the new installer.
The removal of the old version 6.0.0.0 runs ok (all installed files are being removed), but when the installer continues to install the new version, 2 files are missing: a 3rd party DLL and a 3rd party EXE (that haven't been changed) are not being reinstalled.
<Component Id="AutomaticUpdaterWPF.dll" Guid="*">
<File Id="AutomaticUpdaterWPF.dll" Source="AutomaticUpdaterWPF.dll" KeyPath="yes" Checksum="yes" />
</Component>
<Component Id="wyUpdaterProgram" Guid="*">
<File Id="wyUpdaterProgram" Source="wyUpdate.exe" KeyPath="yes" Checksum="yes" />
</Component>
All other files in the < ComponentGroup > (some modified, some unmodified incl. other 3rd party DLLs) are being installed correctly during the major upgrade.
If I click on "repair" after the major upgrade, the 2 missing files re-appear.
Also, if I install version 6.0.1.0 for the first time (no upgrade, but first installation on a clean machine), then those 2 files are installed directly and normally.
(tested on several Windows machine (XP, 7 and 8)
Anybody any suggestion what is wrong and how to fix it?
The log file provided shows that newer versions of a few files already on the machine:
MSI (s) (0C:5C) [16:13:25:890]: Disallowing installation of component: {015A4DC1-56F4-562B-96B5-B3BE0D45FA5F} since the same component with higher versioned keyfile exists
MSI (s) (0C:5C) [16:13:25:890]: Disallowing installation of component: {4B6A1404-3892-5BEF-AB47-8FE3149211A4} since the same component with higher versioned keyfile exists
I've seen this problem with this updater in the past. Christopher is correct. The updater updated its files but didn't tell the MSI (it doesn't update the MSI which is not the correct thing to do). The new MSI thinks newer stuff is on the machine, chooses not to install its files, but during the upgrade the old package removes the files (it doesn't notice that the versions are newer). Since the new installer chose not to install the files you end up with nothing... until the repair.
To work around the problem, you need to move your RemoveExistingProducts action later. If you're using the MajorUpgrade element then Schedule='afterInstallExecute' or Schedule='afterInstallFinalize' should do the trick. You'll need to be more careful with the Component Rules.
Also, IMHO, the 3rd party vendor should not be updating files outside of the MSI. Their decision is forcing your product into a particular way of upgrading.
A log file would help. My guess is it's based on where you have scheduled RemoveExistingProducts. I've seen situations where Costing figures out a file being installed is the same as a file already installed and decides to not install the file. Then the major upgrade occurs and you end up not having the file. The repair works because the file isn't there and costing realizes that it needs to be installed.
I have had the same problem. The issue here is when doing major upgrade, msi at first checks which components to install (and all dlls with lower version than the ones already installed are marked as "do not install"), then it removes installed app and then installs new version but without those previously marked components.
Rescheduling of REP did not help since "disallowing installation (...)" was done in Costing phase and MajorUpgrade can only be scheduled in Install phase.
My solution was to set REINSTALLMODE property to "amus" in wxs file.
<Property Id="REINSTALLMODE" Value="amus" />
The "a" means all dlls will be reinstalled despite their versions.
I had another solution to this problem, but the previous reply certainly pointed me in the right direction. The DLLs in my .NET project were being assigned a lower version number than my previous installation. Going to the AssemblyInfo.cs files and incrementing the third octet from 0 to 1 solved it. Wix now recognized the DLLs as newer.
[assembly: AssemblyVersion("1.0.1.*")]
Error still exists on installer 5.0 and is still a problem.
Workaround to place RemoveExistingProduct after InstallFinalize is no solution for us. I forced the update by property setting on the single file.
This solution works for us now.
On older versions of Windows Installer the issue is documented here:
https://support.microsoft.com/en-us/kb/905238
The list of affected products inplies that it's fixed in MSI engine 4.0 and later. Using the 4.5 redistributable before doing installs should help, if applicable to the OS version.