Wix upgrade: preselect features - wix

we're using Wix to create our installers. We're using the UI where one can select the features that need to be installed. Some features are enabled by default and others are disabled.
However, these defaults are retained when we run an upgrade. We would like the installer to remember what features were installed and enable them in the Feature Tree for upgrading. All other features should be disabled.
We had this code, which seemed to work, but actually, it didn't:
<Feature Id="MainFeature" Level="1" ConfigurableDirectory="INSTALLDIR" Display="expand">
<Feature Id="Feature1" Level="1" InstallDefault="local" AllowAdvertise="no">
<ComponentGroupRef Id="Feature1ComponentGroup" />
<Condition Level="3">(PROJECTUPGRADE AND NOT !Feature1=2)</Condition>
</Feature>
<Feature Id="Feature2" Level="3" InstallDefault="local" AllowAdvertise="no">
<ComponentGroupRef Id="Feature2ComponentGroup" />
<Condition Level="1">(PROJECTUPGRADE AND !Feature2=2)</Condition>
</Feature>
</Feature>

Ah, it seems I was looking in the wrong place. There is an attribute called 'MigrateFeatures' on the UpdgradeVersion tag that specifies this:
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Minimum="$(var.ProductVersion)" IncludeMinimum="yes" OnlyDetect="yes" Property="PROJECTDOWNGRADE" />
<UpgradeVersion Maximum="$(var.ProductVersion)" IncludeMaximum="no" Property="PROJECTUPGRADE" MigrateFeatures="yes" />
</Upgrade>

Related

Wix upgrade msi removing already installed features

I am using the Wix Toolset to generate an .msi for my application. Everything works when I upgrade to a new version, except every time I run a newer version installation the setup doesn't detect already installed features and instead defaults to the features that are 'required' which means if the user installed any of the other features they are removed unless the user explicitly checks them for installation again.
Is there anyway to have the .msi detect which features are currently installed each time a newer version is installed?
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Product Id="*" UpgradeCode="9e578e3d-0119-425c-8633-f54ffaaa4929" Name="#product.name#" Version="#product.version#" Manufacturer="#product.company#" Language="1033">
<Package InstallerVersion="400" Compressed="yes" InstallScope="perMachine" Comments="#product.version#" Description="#product.description#"/>
<Media Id="1" Cabinet="myapp.cab" EmbedCab="yes" />
<!-- Installer Properties -->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
<PropertyRef Id="WIX_IS_NETFRAMEWORK_46_OR_LATER_INSTALLED"/>
<!-- Check Existing Install -->
<Upgrade Id="9e578e3d-0119-425c-8633-f54ffaaa4929">
<UpgradeVersion Minimum="#product.version#" OnlyDetect="yes" Property="NEWERVERSIONDETECTED"/>
<UpgradeVersion Minimum="0.0.0" Maximum="#product.version#" IncludeMinimum="yes" IncludeMaximum="no" Property="OLDERVERSIONBEINGUPGRADED"/>
</Upgrade>
<Condition Message="A newer version of this software is already installed.">NOT NEWERVERSIONDETECTED</Condition>
<!-- Prerequisites -->
<Condition Message="This application requires .NET Framework 4.6 or newer. Please install the .NET Framework then run this installer again.">
<![CDATA[Installed OR WIX_IS_NETFRAMEWORK_46_OR_LATER_INSTALLED]]>
</Condition>
<Condition Message="This application is only supported on Windows 7, Windows Server 2008 R2 or higher.">
<![CDATA[Installed OR (VersionNT >= 601)]]>
</Condition>
...
<Feature Id="Feature_Application"
Title="Application"
ConfigurableDirectory="APPLICATIONDIR"
Level="1"
AllowAdvertise="no">
#product.applicationcomponents#
<ComponentRef Id="ApplicationShortcut" />
<ComponentRef Id="CleanupApplicationData" />
</Feature>
<!-- Feature: My Service -->
<Feature Id="Feature_Service"
Title="My Service"
Description="My Service"
ConfigurableDirectory="REPORTDIR"
Level="3"
AllowAdvertise="no">
#product.servicecomponents#
<ComponentRef Id="ServiceShortcut" />
<Component Id="MyServiceInstaller_ServiceControl" Guid="B72CAA3F-F2DB-48D2-90DD-061209AB2CE5" Directory="REPORTDIR">
<CreateFolder />
<File Id="MyService.exe" Name="MyService.exe" KeyPath="yes" Source="#product.sourcedir#\MyService\MyService.exe"/>
<ServiceInstall Id="MyServiceInstaller_ServiceInstall"
Type="ownProcess"
Vital="yes"
Name="Windows Service"
DisplayName="Windows Service"
Description="Windows service"
Start="auto"
Account="NT AUTHORITY\LocalService"
ErrorControl="ignore"
Interactive="no" />
<ServiceControl Id="MyServiceInstaller_ServiceInstall"
Name="My Service"
Stop="both"
Remove="uninstall"
Wait="yes" />
</Component>
</Feature>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>
<UIRef Id="WixUI_FeatureTree" />
<UI>
<DialogRef Id="FilesInUse" />
<DialogRef Id="MsiRMFilesInUse" />
<!-- Add the GUI logic for installation -->
</UI>
</Product>
#dpb's answer would solve the problem, because the MajorUpgrade tag has a MigrateFeatures attribute with an implicit default value of yes.
However, it is only relevant if you actually want to create a major update to your product, which has implications. - This is not an option for me.
If you do not want to perform a major update, you must add the MigrateFeatures attribute to the UpgradeVersion tag and explicitly set it's value to yes.
The MigrateFeatureStates action below the InstallExecuteSequence tag is of minor importance only.
This action will not be executed if there is no MigrateFeatures="yes" attribute (implicit or explicit), as described above.
If there is a MigrateFeatures="yes" attribute, the MigrateFeatureStates action will automatically be added to the InstallExecuteSequence table of the installer.
You only need to explicitly define the MigrateFeatureStates action in the InstallExecuteSequence tag, if you want to adjust the action's position in the execution sequence.
Try using MajorUpgrade tag.
`<MajorUpgrade DowngradeErrorMessage="Can’t downgrade." />`
https://stackoverflow.com/a/11028847/7165196

Wix Installer to upgrade and remove files + registry entries

I have an application that needs 1. to create DLL files in a Program Files subfolder (e.g. C:\Program Files (x86)\myapp), and 2. to create a registry entry in HKCU. When I run the Remove, I need this subfolder and its files to be deleted, as well as the registry entry.
When I run the installation file of a newer version, I need the new DLL files to replace the existing ones.
I've been struggling getting it to work, having tried several tips from various threads and sites.
So far I get the Program Files to be removed but not the Registry. And I cannot get the file upgrade to work (I change the UpgradeCode & ProductVersion for each new release)
Here is an extract of what I have
<Product Id="$(var.ProductID)"
Name="myapp"
Language="1033"
Version="$(var.ProductVersion)"
UpgradeCode="$(var.UpgradeCode)"
Manufacturer="$(var.Manufacturer)">
<Package Description="Windows installer for myApp $(var.ProductVersion)"
Comments="Execute to install myApp $(var.ProductVersion)"
InstallerVersion="200"
Compressed="yes" />
<Media Id="1" Cabinet="contents.cab" EmbedCab="yes" CompressionLevel="high"/>
<Upgrade Id="$(var.UpgradeCode)">
<UpgradeVersion Minimum="$(var.ProductVersion)"
OnlyDetect="yes"
Property="NEWERVERSIONDETECTED" />
<UpgradeVersion Minimum="1.0.0.0"
IncludeMinimum="yes"
Maximum="$(var.ProductVersion)"
IncludeMaximum="no"
Property="OLDERVERSIONBEINGUPGRADED" />
</Upgrade>
<CustomAction Id="UIandAdvertised" Error="Something about the UI."/>
<Directory Id="TARGETDIR" Name="SourceDir"/>
<Feature Id="Complete"
Title="myApp"
Description="Installation of myApp $(var.ProductVersion)"
Level="1">
<ComponentRef Id="myAppFiles"/>
<ComponentRef Id="RegistryEntry"/>
</Feature>
<Property Id="WIXUI_INSTALLDIR">INSTALLDIR</Property>
<UIRef Id="WixUI_InstallDir"/>
<InstallExecuteSequence>
<RemoveExistingProducts Before="InstallInitialize" />
<RemoveRegistryValues />
</InstallExecuteSequence>
</Product>
My files and reg infos are maintained in a separate file:
<Fragment>
<DirectoryRef Id="TARGETDIR">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="INSTALLDIR" Name="myapp">
<Component Id="myAppFiles" Guid="{xxxx-xxxx-xxxx-xxxx-xxxxxxxx}">
<File Id="myapp.dll" Name="myapp.dll" KeyPath="yes" Source="..\src\bin\x86\Release\myapp.dll" />
</Component>
<Component Id="RegistryEntry" Guid="{xxxxxxx-xxxx-xxxx-xxxx-xxxxxxx}" Win64="no" >
<RegistryKey Root="HKCU" Key="Software\myapp" Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Value="myapp" />
</RegistryKey>
</Component>
</Directory>
</Directory>
</DirectoryRef>
Any help will be highly appreciated.
Use Product ID ="*",
It changes product id guid for each build.
But keep upgrade code same for product, unless you dont want to support upgrade.
You can use major upgrade tag instead of Upgrade tag. It is easier to use.
<MajorUpgrade AllowDowngrades="no"
AllowSameVersionUpgrades="no"
Schedule="afterInstallValidate"
DowngradeErrorMessage="Newer version of [ProductName] is already installed."/>

Remove existing feature from the installed WIX setup

I have a Wix Setup of my .Net appplication.I have installed it on my system.
I want to create a WIX setup with UpgradeVesion to remove some feaures from the installed setup and add new features.
i use the below code:-
<Product Id="*"
Name="MyProduct"
Language="10313"
Version="3.0.0.0"
Manufacturer="My_Company"
UpgradeCode="6ba277d97-41de-4371-a236-b757b7840f7b">
<Package InstallerVersion="200" Compressed="yes" />
<Upgrade Id="6ba28d97-49de-4371-a236-b757b7840f7b">
<UpgradeVersion Minimum="0.0.0.0"
IncludeMinimum="yes"
OnlyDetect="no"
Maximum="3.0.0.0"
IncludeMaximum="yes"
Property="PREVIOUSFOUND" RemoveFeatures="[ProductFeature1]"/>
</Upgrade>
<InstallExecuteSequence>
<RemoveExistingProducts Before="InstallInitialize"/>
</InstallExecuteSequence>
<MediaTemplate />
<UIRef Id="WixUI_InstallDir" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER"/>
<Feature Id="ProductFeature" Title="TestApp" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<Feature Id="ProductFeature1" Title="TestApp" Level="1">
<ComponentGroupRef Id="ProductComponent1"/>
</Feature>
</Product>
But i am unable to remove the ProductFeature1.
How can i remove an existing feature from the installed setup.
You need to create Major upgrade for wix to achieve the same..
follow the below link:-
enter link description here

Run the Update sql Script on Existing Database using WIX Installer during Upgrade

I am creating installer for Creating the databaase using WIX. But I could not able to find a way to run the udate script during Upgrade.
Code for Create DB
<Directory Id="DFDB" Name="DealFoundryDataBase" FileSource="$(var.SolutionDir)DealFoundrySetup/DataBaseScripts">
<Component Id='SqlComponent_Files' Guid='{07DB58E6-5AFC-4BB0-84EC-C5EC6B0E5CA7}' KeyPath='yes'>
<File Id="CreateTable_sql" Name="CreateTable.sql"/>
<File Id="InsertStatements_sql" Name="InsertStatements.sql"/>
<File Id="DFCoreScript_sql" Name="DFCoreScript.sql"/>
</Component>
<Component Id='SqlComponent' Guid='{C5412828-84FB-4CC5-AC71-AC246B9D09E8}' KeyPath='yes'>
<Condition><![CDATA[NOT OLDER_VERSION_FOUND]]> </Condition>
<sql:SqlDatabase Id='SqlDatabase' Database='[PRO_DFDATABASE_NAME]' User='SQLUser' Server='[PRO_DFDATABASE_SOURCE]'
CreateOnInstall='yes' DropOnUninstall='yes' ContinueOnError='yes'>
<sql:SqlScript Id='CreateTable' BinaryKey='CreateTable' ExecuteOnInstall='yes' />
<!--<sql:SqlScript Id='InsertStatements' BinaryKey='InsertStatements' ExecuteOnInstall='yes'/>-->
</sql:SqlDatabase>
</Component>
</Directory>
<Binary Id ='CreateTable' SourceFile='$(var.SolutionDir)DealFoundrySetup/DataBaseScripts/DFCoreScript.sql'/>
<Binary Id ='InsertStatements' SourceFile='$(var.SolutionDir)DealFoundrySetup/DataBaseScripts/InsertStatements.sql'/>
<Binary Id ='MasterData' SourceFile='$(var.SolutionDir)DealFoundrySetup/DataBaseScripts/MasterData.sql'/>
<util:User Id='SQLUser' Name='[PRO_DFDATABASE_USERID]' Password='[PRO_DFDATABASE_PASSWORD]' />
The above lines of code is working fine for creting the DB on Install, but I want to run the update script during upgrade on Existing DB
Plz Help me.
Thanks in Advance.
Ahh... Versioning. So much fun.
First, make sure you have your tags set in the installer. Here is what I usually do (and this is rather complicated because you might want to check for specific versions to do different upgrade scripts):
<Upgrade Id="{YOUR GUID HERE}" > <!--never change me-->
<UpgradeVersion OnlyDetect="yes" Minimum="$(var.ProductVersion)" Property="NEWERPRODUCTFOUND" IncludeMinimum="no" />
<UpgradeVersion OnlyDetect="no" Minimum="5.0.0" Maximum="$(var.ProductVersion)" Property="OLDERVERSIONBEINGUPGRADED" IncludeMaximum="no" RemoveFeatures="All" />
<UpgradeVersion OnlyDetect="yes" Maximum="5.0.0 " Property="VERYOLDVERSIONFOUND" IncludeMaximum="no" />
</Upgrade>
You can have as many of these "versions" defined as you want, and maybe each one will run a different upgrade script for your database. They will set the properties defined in this list.
Secondly, WiX defines a well known value 'Installed' that is only used when you are doing an uninstall or upgrade:
http://msdn.microsoft.com/library/aa369297.aspx
So if you wish to only run it ONLY while doing an upgrade, you should use this:
<Condition><![CDATA[NOT Installed OR NOT VERYOLDVERSIONFOUND]]> </Condition>
If you want to run it if you are doing an upgrade or installing, it should be this way:
<Condition><![CDATA[(NOT Installed AND Installed) OR (NOT VERYOLDVERSIONFOUND AND VERYOLDVERSIONFOUND]]> </Condition>
Which is the same as not having a condition at all since it will always be true.

revert back to previous version of wix installer

When using Visual Studio Setup project, if an installation fails, it will revert back to the previous version of the installation, so it restored the previous files.
But, when using WiX installer, if the installation fails, WiX installer removed all the files on the installed folder.
How can I make WiX installer restore the previous files when the installation fails ?
Thank you.
This is in Product.wxs of a Wix installer for a Windows Service:
<Product Id="*" Name="WixWindowsService2012" Language="1033" Version="1.0.0.1" Manufacturer="aaa" UpgradeCode="blabla">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" Platforms="x64"/>
<Upgrade Id="blabla">
<UpgradeVersion OnlyDetect="no" Property="PREVIOUSFOUND"
Minimum="1.0.0.0" IncludeMinimum="yes"
Maximum="99.0.0.0" IncludeMaximum="no" />
</Upgrade>
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="WixWindowsService2012" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
:
<Component Id="ProductComponent" Win64="yes">
<File Id="WixWindowsService2012.exe" Name="WixWindowsService2012.exe" Source="$(var.WixWindowsService2012.TargetPath)" Vital="yes" KeyPath="yes" DiskId="1"/>
<ServiceInstall
Id="ServiceInstaller"
Type="ownProcess"
Vital="yes"
Name="WixWindowsService2012"
DisplayName="WixWindowsService2012"
Description="A test for WiX installation for Windows Service"
Start="auto"
Account="LocalSystem"
ErrorControl="ignore"
Interactive="no"></ServiceInstall>
<ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="WixWindowsService2012" Wait="yes" />
</Component>
If you had a setup that restored previous versions of the files then by definition it was an upgrade (RemovePreviousVersions in Visual Studio). In WiX you specify an upgrade by using the MajorUpgrade element, so whatever you have in yours isn't sufficient or isn't working. Your UpgradeCode in the WiX project needs to be the same as your previous setup, whether it's WiX or VS. The ProductVersion must be incremented in the first 3 digits, and the ProductCode must be different. In addition, a per-machine install will not upgrade a per user install, just in case that's happening. Creating a verbose log of the install will supply the reason why your upgrade isn't working.