I want to execute my Custom Action if user is unselecting a specific feature. It doesn't matter if this is during a Repair
, Upgrade
or Uninstall
.
The action should not be executed, when during a Upgrade the feature is reinstalled.
With my research: Action-Conditions, Conditional Statement Syntax, Property-Table, _UPGRADE Property, execute an action only on Uninstall, neither on repair, nor upgrade nor install
I come to this solution:
_UNINSTALLONLY Property, that help to execute the Custom Action only on uninstall:
<SetProperty Id="_UNINSTALLONLY" After="FindRelatedProducts" Value="1">
<![CDATA[Installed AND NOT UPGRADINGPRODUCTCODE]]></SetProperty>
And my deferred CustomAction inside my InstallExecuteSequence
:
<Custom Action="HandleMyFeatureMyCustomActionOnUnselect" Before="InstallFinalize">
<![CDATA[_UNINSTALLONLY AND (!MyFeature >= 2) AND (&MyFeature <= 2) ]]></Custom>
This works, expect when User is unselecting feature on upgrade. Then the action is not called.
I tried:
(!MyFeature >= 2) AND (&MyFeature <= 2)
: Problem: Action is called on upgrade, even User doesn't change selection
_UNINSTALLONLY AND (&MyFeature <= 2)
: Problem: Action is also called, when I unselect another Feature2 on Upgrade
Now I feel a little bit lost.
Another requirement is that, during a product upgrade, the old version is reliably removed. Additionally, it is important to preselect the features based on their current status in the setup. I have successfully achieved this. To rule out any interactions with my issue, here is some additional context:
<CustomAction Id="HandleMyFeatureMyCustomActionOnUnselect" BinaryKey="FeatureCustomActions"
DllEntry="HandleMyFeatureMyCustomActionOnUnselect" Impersonate="no" Execute="deferred"
Return="check" />
<CustomAction Id="SetHandleMyFeatureMyCustomActionOnUnselectPropertyValues" Property="HandleMyFeatureMyCustomActionOnUnselect"
Value="INSTALLFOLDER=[INSTALLFOLDER]" />
<Property Id='INSTALLFEATURE'>
<RegistrySearch Id='InstallFEATURE' Root='HKLM'
Key='SOFTWARE\Somewhere\AnotherKey'
Name='FEATUREINSTALLED' Type='raw' />
</Property>
The InstallExecuteSequence
<InstallExecuteSequence>
<Custom Action="SetREINSTALL" Before="CostInitialize">
Installed AND REMOVE ~= "" AND NOT REINSTALL
</Custom>
<RemoveExistingProducts After="InstallInitialize"/>
...
<Custom Action="SetHandleMyFeatureMyCustomActionOnUnselectPropertyValues" Before="HandleMyFeatureMyCustomActionOnUnselect" ><![CDATA[_UNINSTALLONLY AND (!MyFeature >= 2) AND (&MyFeature <= 2) ]]></Custom>
<Custom Action="HandleMyFeatureMyCustomActionOnUnselect" Before="InstallFinalize"><![CDATA[_UNINSTALLONLY AND (!MyFeature >= 2) AND (&MyFeature <= 2) ]]></Custom>
...
</InstallExecuteSequence>
The Features
<Feature Id="MyFeature" Title="My Feature" ConfigurableDirectory="INSTALLFOLDER" Display="expand" Level="1">
<Condition Level="2">INSTALLFEATURE=0</Condition>
<ComponentGroupRef Id="FEATURE"/>
</Feature>
<Feature Id="MyFeature2" Title="My Feature2" ConfigurableDirectory="INSTALLFOLDER" Display="expand" Level="1">
<Condition Level="2">INSTALLFEATURE2=0</Condition>
<ComponentGroupRef Id="FEATURE2"/>
</Feature>
So my question is:
How to execute a custom action when a user changes a feature from 'selected' to 'unselected'?
I solved it, with
<SetProperty Id="_NEWINSTALLER" After="FindRelatedProducts" Value="1">
<![CDATA[NOT UPGRADINGPRODUCTCODE]]></SetProperty>
and the condition
<Custom Action="SetHandleMyFeatureMyCustomActionOnUnselectPropertyValues" Before="HandleMyFeatureMyCustomActionOnUnselect" >
<![CDATA[_NEWINSTALLER AND (!MyFeature >= 2) AND (&MyFeature <= 2) ]]></Custom>
<Custom Action="HandleMyFeatureMyCustomActionOnUnselect" Before="InstallFinalize">
<![CDATA[_NEWINSTALLER AND (!MyFeature >= 2) AND (&MyFeature <= 2) ]]>
</Custom>
I was so damn close! Now it's going through the test :-)