1

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>
devfunkd
  • 3,164
  • 12
  • 45
  • 73
  • Seems odd, the MigrateFeatureStates standard action should be taking care of this unless your UI is re-setting the states back to 'default' values. I would suggest doing the upgrade twice, once with the UI (msiexec /i install.msi /l*v UILog.txt) and once quietly (msiexec /i install.msi /qn /l*v quietLog.txt) and see what happens with the feature states. – Brian Sutherland Apr 04 '17 at 21:08
  • you could use (!FeatureID=3) to detect if feature is installed. Check link for more information : https://www.firegiant.com/wix/tutorial/com-expression-syntax-miscellanea/expression-syntax/ – Ashish Kamat May 17 '17 at 11:12
  • I've got the same problem as described in this question. The comment of @AshishKamat regarding expressions seems to point to the right direction, but I was unable to create a working solution based on that yet. Can someone please provide a working example? I will add a bounty... – PhilS Sep 28 '21 at 10:11

2 Answers2

0

@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.

PhilS
  • 1,634
  • 14
  • 23
-2

Try using MajorUpgrade tag.

`<MajorUpgrade DowngradeErrorMessage="Can’t downgrade." />`

https://stackoverflow.com/a/11028847/7165196

Community
  • 1
  • 1
dpb
  • 9
  • 2
  • I cannot see how this answer is supposed to solve the problem. – PhilS Sep 28 '21 at 10:14
  • This answer is not as bad as I originally thought. It would solve the problem in some circumstances. However, neither this answer nor the linked thread provide an explanation as to why this would be helpful. – PhilS Sep 28 '21 at 12:47