I should start by clarifying that I am a complete novice and unfamiliar with Wix, so I am relying on looking at other examples.
I have an installer that is working fine but the filename for the MSI needs to change.
My 'Product' section looks roughly like this:
<Product Id="*" Name="MyShellExtension" Language="1033" Version="1.0.0.0" Manufacturer="ACME Inc" UpgradeCode="???????-????-????-????-??????????">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="MyShellExtension" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<CustomActionRef Id="InstallShell"/>
</Product>
I found this posting but it's quite old and refers to a property called 'OutputName' that does not appear to be supported in Wix v3.11 which is what I have. WIX: Howto set the name of the msi output file dynamically
BTW when I installed "The latest version" of Wix I found that it had installed 3.11. I'm guessing it's because I'm running Visual Studio 2019 but if that's not the case and it's both possible and recommended to run more recent versions with VS 2019, please advise on where I might have gone wrong with the installation of Wix.
I found that I could right-click the project in Visual Studio and manually set the name there, which solved my initial problem, but I would like to add the version number of the component I'm installing to the filename.
I'm very new to all of this so it would be really helpful to have an example that I can paste in and modify.
The OutPut name property is in a .wixproj MSBuild file if your using VisualStudio / Votive / MSBuild. If your calling candle and light it's not used. You just pass in the parameter to set the output file name.
Related
I have a simple installer and I want to be able to perform upgrades and do proper uninstalls without having to manually generate a new ID each time.
This is my code (the relevant parts):
<Product Id="*" UpgradeCode="$(var.UpgradeCode)" Name="$(var.ProductName)"
Language="!(loc.Language)" Codepage='1252' Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)">
<Package Id='*' Keywords='Installer' Description="My Installer" Manufacturer='$(var.Manufacturer)'
InstallPrivileges='elevated' InstallScope='perMachine'
InstallerVersion='200' Compressed='yes'/>
<MajorUpgrade Schedule="afterInstallValidate"
DowngradeErrorMessage="A later version of [ProductName] is already installed"
AllowSameVersionUpgrades="yes"
AllowDowngrades="no" />
<InstallUISequence>
<Show Dialog="WelcomeDlg" After="CostFinalize" />
</InstallUISequence>
</Product>
The problem is that I cannot seem to get upgrades and uninstalls to work with the same code/installer.
If I use Product Id="*", I'm able to perform upgrades, but when I try to uninstall, only the entry from Add/Remove Programs is removed. The installed files, however, remain in Program Files.
If I use Product Id="some random guid", I'm able to uninstall, but I'm no longer able to perform upgrades.
So my questions is:
Can I perform upgrades and uninstalls with a wildcard Id (i.e. Product Id="*"), or do I have to manually generate a new ID each time?
Thanks!
I used (Product Id="*") in my WiX installer and it is still able to perform upgrades and uninstalls. My code for Product, Package and Major Upgrade look almost identical to yours so I think the problem lies somewhere else.
Do you have this in your Product section to tell WiX which component groups to install/uninstall? (see code)
<Feature Id="ProductFeature" Title="[ProductName]" Level="1">
<ComponentGroupRef Id="ComponentGroup1" />
<ComponentRef Id="DesktopApplicationShortcut" />
</Feature>
Edit: I have since noticed one other thing that may help you out. I was recently having issues with my program not removing the Desktop Shortcut during Uninstall, despite it working in the past. I have since changed the Guid from "*" to a Guid code and it is now being removed. I think it is the program recognizing the Component.
<Component Id="DesktopApplicationShortcut" Guid="{Create Guid Code}">
We are using the following code in our Wix Packages.wxs file, as per the documentation we are changing the UpgradeCode GUID & Version number from. 1.0.1.0 to 1.0.2.0 but when we build and try to install the msi package it says older version is still installed and we need to uninstall it to continue.
<Product Id="8B3DFDFF-D894-4A31-AA92-824729385F15" Name="WixCodeBase" Language="1033" Version="1.0.2.0" Manufacturer="Company Name" UpgradeCode="C78D9362-A156-44A2-94D0-AFA19389FFE8">
<Package Id="*" Keywords="Installer" Manufacturer="Company Name" Description="Wix Installer" InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade Schedule ="afterInstallValidate" AllowDowngrades="no" DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Media Id='1' Cabinet='WixPackage.cab' EmbedCab='yes' />
Installer Error
For major upgrades, you change the Product element's Id attribute not the UpgradeCode attribute. In fact, UpgradeCode attribute must remain constant across versions to use the MajorUpgrade element. MSDN has all the details.
I maintain an open source project called IsWiX that provides templates and designers to accelerate the WiX / MSI learning and development process. One of the many things these templates do out of the box is provide proper Major Upgrade support. Consider this code generated by the template:
Code Source
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<!--
MSIProductVersion is defined in DesktopApplication.wixproj as 0.0.1 for local desktop builds.
You should pass in the MSBuild Property 'MSIProductVersion' to override it during an automated build.
See http://msdn.microsoft.com/en-us/library/windows/desktop/aa370859%28v=vs.85%29.aspx for information on allowable values.
The Product#Id attribute (ProductCode Property) will be a random GUID for each build. This is to support "Major Upgrades" where each install
is a seamless uninstall/reinstall.
-->
<Product Id="*" Name="DesktopApplication" Language="1033" Version="$(var.MSIProductVersion)" Manufacturer="DesktopApplication" UpgradeCode="7220a19b-ed49-4cd1-8002-6af7926441b4">
<Package InstallerVersion="301" Compressed="yes" InstallScope="perMachine" />
<MediaTemplate EmbedCab="yes" />
<!-- Major Upgrade Rule to disallow downgrades -->
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<!--Common Launch Condition-->
<!-- Examples at http://wixtoolset.org/documentation/manual/v3/customactions/wixnetfxextension.html -->
<PropertyRef Id="NETFRAMEWORK40FULL"/>
<Condition Message="[ProductName] requires .NET Framework 4.0.">Installed OR NETFRAMEWORK40FULL</Condition>
<!-- Include User Interface Experience -->
<Icon Id="Icon.ico" SourceFile="Resources\Icon.ico"/>
<Property Id="ARPPRODUCTICON" Value="Icon.ico"></Property>
<UIRef Id="UI"/>
<!-- Include Features and Directories Fragment -->
<DirectoryRef Id="INSTALLLOCATION"/>
</Product>
</Wix>
In addition to be documented in the comments, it's also discussed in the tutorials.
In a nutshell, you need to keep UpgradeCode the same and randomize ProductCode.
I've made an installer using the WIX toolset (3.10). I'd like to enable upgrades but I can't make it work. Every time I run the msi it installs another version.
I can't figure out what's wrong. can anyone advise?
<Product Id="*"
Name="$(var.PRODUCTNAME)"
Language="1033"
Version="$(var.PRODUCTVERSION)"
Manufacturer="Manufacturer"
UpgradeCode="UPGRADE_CODE"
>
<Package InstallerVersion="200"
Compressed="yes"
InstallScope="perMachine" />
<MajorUpgrade Schedule="afterInstallInitialize"
AllowDowngrades="no"
AllowSameVersionUpgrades="no"
DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
AllowSameVersionUpgrades="yes" will probably fix this. When you test upgrades you need to either always update the version (one of the first 3 parts) between installers or just allow the same version upgrades.
from the wix website
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.
So your install thinks these two installs are separate things even though they share the same upgrade code which is why you get 2 copies in your add remove programs list.
I use a GUID for the UpgradeCode (I suppose that's what UPGRADE_CODE means).
You can also set the REINSTALLMODE property to change your reinstallation behavior.
It could look like this:
<SetProperty Id="REINSTALLMODE" Value="amus" After="FindRelatedProducts">Installed AND REMOVE<>"ALL"</SetProperty>
Just be aware that a will reinstall your product regardless of the installed version. But you can look up which characters you need for your installer.
For Value="amus" you can refer to the Microsoft documentation here
In addition to your MajorUpgrade property it is crucial that your UpgradeCode does not change for future versions. Might that be the problem?
Premise
I am using WiX Toolset 3.5.
I have successfully released several patches for my product that use the same UpgradeCode and ProductCode. However, the most recent two patches incorrectly went out with a different UpgradeCode. These patches installed successfully, but my latest patch refuses to install.
Here is my release history since the last MSI release:
Installer (10.0.20935.0) with UpgradeCode A.
Patch (10.0.21069.0) with UpgradeCode A.
Patch (10.0.21188.0) with UpgradeCode A.
Patch (10.0.21334.0) with UpgradeCode A.
Patch (10.0.21671.0) with UpgradeCode A.
Patch (10.1.0.264) with UpgradeCode B.
Patch (10.1.0.21682) with UpgradeCode C.
Patch (10.2.0.0), the latest patch, fails regardless of whether I use UpgradeCode A, B or C.
Below is the error message that appears when I try to install patch 10.2.0.0:
The upgrade patch cannot be installed by the Windows Installer service because the program to be upgraded may be missing, or the upgrade patch may update a different version of the program. Verify that the program to be upgraded exists on your computer and that you have the correct upgrade patch.
The user is not allowed to install the patch.
Question
I need to release a patch that
installs successfully on production (10.1.0.21682).
allows me to continue releasing patches in the future.
How do I achieve this?
What have I tried?
I have tried the following, with no success:
Changing the UpgradeCode to A, i.e. the one from 10.0.21671.0 and earlier.
Changing the UpgradeCode to B, i.e. the one from 10.1.0.264.
Changing the UpgradeCode to C, i.e. the one from 10.1.0.21682.
Changing the ProductCode.
Creating a patch straight from 10.0.21671.0 to 10.2.0.0 (though of course in production it will be run on 10.1.0.21682).
All of the above scenarios result in the same error message (given in the premise). I have also found the following question on StackOverflow:
WIX: When upgrading, what to do when there are 2 different UpgradeCodes?
This led to me adding OnlyDetect="no" to the <UpgradeVersion> element of a new <Upgrade> element in my product's .wxs file:
<Upgrade Id="UpgradeCode C">
<UpgradeVersion Property="OLD_PRODUCT_FOUND"
IncludeMaximum="yes"
Maximum="10.2.0.0"
MigrateFeatures="yes"
OnlyDetect="no" />
</Upgrade>
However, this had the exact same outcome as before.
Sample Code
I have created a small project that I use to replicate my scenario.
Below is the .wxs file for version 10.2.0.0 of the product from my test project:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="{8CB0CC73-82B1-495E-B768-D1C38372678A}"
Name="Sample Application"
Language="1033"
Version="10.2.0.0"
Manufacturer="Sample Corporation"
UpgradeCode="{7E72848F-FC99-4737-87DE-91C738B7C5EE}">
<Package Description="Installs a file that will be patched."
Comments="This Product does not install any executables"
InstallerVersion="200"
Compressed="yes" />
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
<FeatureRef Id="SampleProductFeature"/>
</Product>
<Fragment>
<Feature Id="SampleProductFeature" Title="Sample Product Feature" Level="1">
<ComponentRef Id="Sample.txt" />
</Feature>
</Fragment>
<Fragment>
<DirectoryRef Id="SampleProductFolder">
<Component Id="Sample.txt" Guid="{d738b2a9-0dbc-4381-9efd-5801723b1569}" DiskId="1">
<File Id="Sample.txt" Name="Sample.txt" Source=".\$(var.Version)\Sample.txt" />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="SampleProductFolder" Name="Patch Sample Directory">
</Directory>
</Directory>
</Directory>
</Fragment>
</Wix>
Below is the .wxs file for the patch to version 10.2.0.0:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Patch
AllowRemoval="no"
Manufacturer="Sample Corp"
MoreInfoURL="http://www.dynamocorp.com/"
DisplayName="Sample Patch"
Description="Small Update Patch"
Classification="Update"
OptimizedInstallMode="yes">
<Media Id="8000" Cabinet="RTM.cab" CompressionLevel="none">
<PatchBaseline Id="RTM">
</PatchBaseline>
</Media>
<PatchFamilyRef Id="SamplePatchFamily"/>
</Patch>
<Fragment>
<PatchFamily Id='SamplePatchFamily' Version='10.2.0.0' Supersede='no'>
</PatchFamily>
</Fragment>
</Wix>
You definitely shouldn't change the ProductCode. If you have been building MSI files that changed the UpgradeCode then maybe more critical items are changing. You built a patch that targets a product with a specific ProductCode and PackageCode (based on the MSI files you created) and that's what it wants.
Most importantly, I'd check that patch 7 with UpgradeCode C did not change the installed product's ProductCode or PackageCode because that's the patch that produced the problem, and if your new patch 8 cannot find a product to patch it's the ProductCode and PackageCode it'll be looking for. That's what the error is saying - the ProductCode (or PackageCode) targeted by this patch is not installed. In other words I doubt very much that the UpgradeCode matters in that error message, and that linked article about upgrading more than one product with a major upgrade has no bearing on a patching issue like this unless you are worried about major upgrades, in which case you just list all the UpgradeCodes that need upgrading, and so it's not an issue.
The solution, it turns out, is as simple as disabling validation of the UpgradeCode for the newest patch. This can be done by setting the UpgradeCode attribute on the Validate to "no".
<Media Id="8000" Cabinet="RTM.cab" CompressionLevel="none">
<PatchBaseline Id="RTM">
<Validate UpgradeCode="no" />
</PatchBaseline>
</Media>
This 10.2.0.0 patch, which introduces a new UpgradeCode, runs successfully on top of 10.1.0.21682, and I was able to successfully execute three subsequent patches. (These patches have UpgradeCode validation enabled and share the same UpgradeCode as 10.2.0.0.)
I have a set of WiX scripts that used to allow me to create patches for patches, e.g. I would have full installers for the following version numbers:
11.00.38.01
11.00.38.02
11.00.38.03
I would then create patches between these numbers, i.e.
11.00.38.01-11.00.38.02
11.00.38.02-11.00.38.03
Using these scripts with WiX 3.0 I would be able to run
11.00.38.01
and then apply the
11.00.38.01-11.00.38.02 and 11.00.38.02-11.00.38.03 patches,
which would bring the installation up to
11.00.38.03
After upgrading to WiX 3.6 and later 3.7 and 3.8, this no longer works.
I can install one build and apply one patch to that build but I cannot install a build, patch the installation, and then apply another patch.
If I attempt to do that, I get the following error:
The upgrade patch cannot be installed by the Windows Installer service
because the program to be upgraded may be missing, or the upgrade
patch may update a different version of the program. Verify that the
program to be upgraded exists on your computer and that you have the
correct upgrade patch.
My patch template looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Patch
AllowRemoval="no"
Manufacturer="Acme"
MoreInfoURL="http://www.acme.com/"
DisplayName="$(var.ProductName) $(var.ProductVersion) Upgrade"
Description="Minor Upgrade"
Classification="Update"
>
<Media Id="5000" Cabinet="RTM.cab">
<PatchBaseline Id="RTM"/>
</Media>
<PatchFamilyRef Id="$(var.ProductShortName)UpgradeFamily"/>
</Patch>
<Fragment>
<PatchFamily Id='$(var.ProductShortName)UpgradeFamily' Version='1.0.0.0' Supersede='yes'>
<ComponentGroupRef Id='PatchComponents' />
</PatchFamily>
</Fragment>
</Wix>
Part of the .wxs script for the product looks like this:
<Product Name='Acme Server'
Id='6DE00366-36D8-4BA0-B911-8FBD7490C472'
UpgradeCode='0FDE99AC-D910-46CF-814D-D851B81D3816'
Language='1033'
Codepage='1252'
Version='$(var.ProductVersion)'
Manufacturer='Acme'>
<Package
Id='*'
Keywords='Installer'
Description="Acme Server"
Comments='Acme Server is a registered trademark of Acme.'
Manufacturer='Acme'
InstallerVersion='200'
Languages='0'
Compressed='yes'
SummaryCodepage='1252'
Platform='x86'
/>
<Upgrade Id='0FDE99AC-D910-46CF-814D-D851B81D3816'>
<UpgradeVersion OnlyDetect='yes' Property='SELFFOUND'
Minimum='$(var.ProductVersion)' IncludeMinimum='yes' Maximum='$(var.ProductVersion)' IncludeMaximum='yes' />
<UpgradeVersion OnlyDetect='yes' Property='NEWERFOUND'
Minimum='$(var.ProductVersion)' IncludeMinimum='no' />
</Upgrade>
</Product>
The interesting thing is that the WiX 3.0 patch log contains the following line:
PATCH SEQUENCER: verifying the applicability of minor upgrade patch
c:\Install\10.10.11.01-10.10.11.02\AcmeServer.msp against product
code: {6DE00366-36D8-4BA0-B911-8FBD7490C472}, product version:
10.10.1101, product language 1033 and upgrade code: {0FDE99AC-D910-46CF-814D-D851B81D3816}
whereas the WiX 3.6+ patch log contains this line:
PATCH SEQUENCER: verifying the applicability of QFE patch
c:\11.00.38.01-11.00.38.02\AcmeServer.msp against product code:
{6DE00366-36D8-4BA0-B911-8FBD7490C472}, product version: 11.00.3801,
product language 1033 and upgrade code:
{0FDE99AC-D910-46CF-814D-D851B81D3816}
Notice that the 3.0 log says "minor upgrade patch" whereas the 3.6+ log says "QFE patch". I do not know if this is relevant here.
What could I be doing wrong here? Why did the behavior of the generated patches change? Of course, there have been minor tweaks to the WiX scripts over the past couple of years but as far as I know none of them were related to the patching process. It seems as if the main change was due to the switch from WiX 3.0 to a newer version.
EDIT:
I have verified that this change happened exactly at the time I switched from WiX 3.0 to WiX 3.6.
I have also noticed that if I apply the WiX 3.0-generated patches, the version number is updated in Programs & Features when a patch is applied to a full installation or another patch whereas with the WiX 3.6+-generated patches, the version number stays the same when a patch is applied to a full installation.
I am wondering if any defaults have changed for the command-line tools (torch, pyro, etc)?
The solution was to add a ProductVersion property reference to the PatchFamily element as seen in the snippet below:
<Fragment>
<PatchFamily Id='$(var.ProductShortName)UpgradeFamily' Version='1.0.0.0' Supersede='yes'>
<PropertyRef Id="ProductVersion"/>
<ComponentGroupRef Id='PatchComponents' />
</PatchFamily>
</Fragment>
That was all there was to it.
I do not see this mentioned in any of the documentation or the usual, old sample patch script found on the web, though now that I know what to look for, it is easy enough to find discussions about it.
As I mentioned in my original question, this element was not necessary when using WiX 3.0 which might go some way to explain its absence from the old patch sample.