4

I am trying to put together an installer using WiX 3.0 and I'm unsure about one thing. I would like to use the FeaturesDlg dialog to allow the users to select features to install, but I need to be able to conditionally exclude some features from the list based on some input previously received, preferably from a managed Custom Action.

I see that if I set the Display attribute of a Feature to hidden in the .wxs file that it does what I want, but I can't figure out a way to change that attribute at runtime.

Any pointers would be great.

Edit:

I tried using SQL to update the session Database, but while I can actually delete the feature using DELETE FROM Feature WHERE Feature = 'featureId', if I try to use UPDATE Feature SET Display=0 WHERE Feature='featureId', I get an UPDATE FAILED error. If I try to set the Display value to anything other than what it's already set at I get that error.

Deleting the feature is ALMOST good enough, but I would need to be able to go back and re-add the feature if the user goes Back and changes some input data.

Yan Sklyarenko
  • 31,557
  • 24
  • 104
  • 139
Gerald
  • 23,011
  • 10
  • 73
  • 102

3 Answers3

3

Well I think I found a solution by accident. After a bunch of experimenting I ran across an error message from MSI that kinda described some columns for the Feature table in the current session, and there was a column "RuntimeLevel" that is not described in any docs that I could find. So I tried this:

session.Database.Execute("UPDATE Feature SET RuntimeLevel=0 WHERE Feature='MyFeature'");

And it worked; the feature was no longer listed in the SelectionTree. Then I ran the same query again with RuntimeLevel=1, and it was listed again.

Since I'm not sure if there are any strange implications for this solution I am going to leave the question open for a while longer, just in case somebody else has a "better" solution.

Gerald
  • 23,011
  • 10
  • 73
  • 102
  • It's undocumented. People will just point and laugh if/when the Windows Installer changes its internal workings and breaks you. – Rob Mensching May 01 '10 at 22:40
  • 1
    Maybe, but working now and breaking later is better than never working at all in this case. Doing a Google search found somebody that came across the exact same error message with the exact same internal database columns in 2005, so I'll take my chances that it's not going to change anytime soon, unless/until I find a better solution, or Microsoft makes WI more flexible. – Gerald May 01 '10 at 23:16
  • This is the only working solution if the conditions are dynamic (changed by another installer dialog.) The other two solutions do not work. – Rex Hui Apr 05 '21 at 04:56
3

I needed to do the same and found this...

Create a property.. which will be set by the CA or whatever...

  <Property Id='INSTALL_FEATURE_2'>YES</Property>

Then use the property inside your feature...

  <Feature Id='ASecondFeature' Title='Feature 2' Level='1'>
    <Condition Level='0'>INSTALL_FEATURE_2 = "NO"</Condition>
    <ComponentGroupRef Id='secondComponent'/>  
  </Feature>

note the the condition dosent directly set whether the parent is installed as with files and the like, it sets the Level attribute on the parent feature. Setting it to 0 makes it hidden... voilà!

S Rosam
  • 375
  • 1
  • 3
  • 16
3

The example above is the correct way to conditionally offer a feature (except that it's recommended that the condition should be in a CDATA section), however since you said you wanted to decide this in your custom action...

Given a feature like this:

<Feature Id="MyFeature" Title="My Title" Level="1" >
  <Condition Level="0"><![CDATA[NOT(INSTALLMYFEATURE~="TRUE")]]></Condition>
  <ComponentGroupRef Id="MyFeatureComponentGroup" />
</Feature>

In your managed custom action you receive a "Session" object. If you want to make the feature available for the user, set the INSTALLMYFEATURE property to "True", otherwise set it to "False".

session["INSTALLMYFEATURE"] = "True";

or

session["INSTALLMYFEATURE"] = "False";
Tom Faust
  • 1,385
  • 11
  • 11