How to install a feature dependant on a condition - wix

I'm trying to install a feature if the condition is true.
According to tutorials it should work like this:
<Feature Id='ParentFeature' Id='Default'
Title='Wix Sample App'
Description='The complete package of Wix Sample App.'
Display='expand'
Level='1'
ConfigurableDirectory='INSTALLDIR'>
<Feature Id='ChildFeature' Title='AppConfig Internal' Level='1'>
<ComponentRef Id='MyApp.exe' />
</Feature>
<!-- This is the conditional feature -->
<Feature Id='OptionalChildFeature' Title='AppConfig Internal' Level='0'>
<ComponentRef Id='MyApp.exe.config' />
<Condition Level='1'><![CDATA[TRUE]]></Condition>
</Feature>
</Feature>
My example results in NOT getting the optional feature installed, but I expected it to get installed.
The resources I used:
wix tutorial
stackoverflow question
Update:
I tried to make a prototype with which didn't work. finally worked and I could identify the problem in previous steps (a property was not correctly set).

You're condition of "TRUE" doesn't make sense. TRUE would be a public property called TRUE. Presumably, nothing set it to have a value so the condition evaluates to false and hence the feature remains at InstallLevel 0 and isn't installed.

Related

Why can't I select individual features from my FeatureGroup when I use FeatureGroupRef?

I have a FeatureGroup in a Fragment that looks something like this:
<Fragment>
<FeatureGroup Id="ConsolidatedFeatureCollection">
<ComponentGroupRef Id="ComponentCollection" />
<Feature Id="Feature1" Title="Feature1" Level="1" AllowAdvertise="no" >
<ComponentRef Id="Component1" />
</Feature>
<Feature Id="Feature2" Title="Feature2" Level="1" AllowAdvertise="no" >
<ComponentRef Id="Component2" />
</Feature>
<Feature Id="Feature3" Title="Feature3" Level="1" AllowAdvertise="no" >
<ComponentRef Id="Component3" />
</Feature>
<Feature Id="Feature4" Title="Feature4" Level="1" AllowAdvertise="no" >
<ComponentRef Id="Component4" />
</Feature>
</FeatureGroup>
And I reference this FeatureGroup from my main feature like this:
<Feature Id="MainFeature" Title="Super Awesome Program" Level="1" AllowAdvertise="no" InstallDefault="local" Display="expand">
<FeatureRef Id="SomeOtherFeature"/>
<FeatureGroupRef Id="ConsolidatedFeatureCollection"/>
</Feature>
The FeatureGroup documentation says that it "groups together multiple components, features, and merges to be used in other locations." And the FeatureGroupRef documentation says that it is used to "create a reference to a FeatureGroup in another Fragment." It seems pretty straight forward, so I would expect that using this FeatureGroupRef as I have above would produce exactly the same result as using a FeatureRef for each individual Feature:
<Feature Id="MainFeature" Title="Super Awesome Program" Level="1" AllowAdvertise="no" InstallDefault="local" Display="expand">
<FeatureRef Id="SomeOtherFeature"/>
<FeatureRef Id="Feature1"/>
<FeatureRef Id="Feature2"/>
<FeatureRef Id="Feature3"/>
<FeatureRef Id="Feature4"/>
</Feature>
In fact, this seems to be exactly the purpose of the FeatureGroup element. Not so, when I use <UIRef Id="WixUI_FeatureTree"/> or any reference to the FeaturesDlg. Using the FeatureGroupRef, I cannot install individual Features. If any one of the Features in the group is selected, ALL are installed. You never see any indication of this in the UI, but they are installed.
I'm using the stable release of WIX toolset 3.8 (v3.8.1128.0), and I'm rather new to WIX, so I'm hesitant to assume that such a large bug has escaped the community for several months. Am I missing something about the way FeatureGroups work? And is there a work-around to allow selection of individual Features, other than a FeatureRef for every single Feature? (in real life, there are a lot more than four, and several projects which will use them)
I figured out what's wrong. It's a little embarrassing. ComponentCollection is the ComponentGroup that contains Component1, Component2, Component3, and Component4. I added that to the FeatureGroup because I thought that I needed to reference where these components are coming from. What I was actually doing was including all of the Components in the FeatureGroup. I was under the impression that a FeatureGroup simply contained Features, but apparently, it can install content of its own independent of its Features.
Once I removed <ComponentGroupRef Id="ComponentCollection" /> from the FeatureGroup, I started getting the behavior that I expected.

wix 3.6 ComponentGroupRef Id="Product.Generated" gives error, wix 3.5 does not

I just updated wix to 3.6 and after the upgrade my wix project failed to build.
The following line in the xml triggers the error:
<ComponentGroupRef Id="Product.Generated"/>
The error explanation is the following:
error LGHT0094: Unresolved reference to symbol 'WixComponentGroup:Product.Generated' in section 'Product:*'.
If I comment out the ComponetGroupRef element, the msi is created without any errors and it seems to work just as before the upgrade to 3.6.
Fails:
<Feature Id="ProductFeature" Title="My.net Server" Level="1">
<ComponentRef Id="My.Server" />
<ComponentRef Id="My.Server.exe.config"/>
<!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. -->
<ComponentGroupRef Id="Product.Generated" />
</Feature>
Works:
<Feature Id="ProductFeature" Title="My.net Server" Level="1">
<ComponentRef Id="My.Server" />
<ComponentRef Id="My.Server.exe.config"/>
</Feature>
Could anyone shed some light on this error? Am I breaking something that I should be aware of or fix? How important is that entry and what exactly does it do?
Exact same question posted today, LGHT0094: Unresolved reference to symbol 'WixComponentGroup:Product.Generated' in section 'Product:*' You should search before asking a question, apologies came across a little rude there, was in a rush. Always good just to do a quick search before posting, it will prevent downvoting..:)

Wix: How to set a Feature State "This Feature Will Not be available"?

I've assigned a task in which one sub feature among 4 should be displayed to the user in the state as "This Feature Will Not be available"
For instance, I have this feature set:
<Feature Id="Main" AllowAdvertise="no" ConfigurableDirectory="MYROOT" Description="Required components" Display="expand" Level="1" Title="Main Feature" Absent="disallow">
<ComponentRef Id ="Cmp22"/>
<Feature Id="SubFeature_1" AllowAdvertise="no" Level="1">
</Feature>
<Feature Id="SubFeature_2" AllowAdvertise="no" Level="1">
</Feature>
<Feature Id="SubFeature_3" AllowAdvertise="no" Level="1">
<!-- I want this feature to displayed as "This Feature Will Not be available" -->
</Feature>
</Feature>
I've tried with different Level values.
Also, I used a VbScript custom action using Session.FeatureRequestState method, to change it at runtime, but can't get enough results.
Can someone please guide me about this?
Thanks and Best regards
Set the level to a value higher than INSTALLLEVEL property value:
http://msdn.microsoft.com/en-us/library/aa369536(VS.85).aspx
For example, if INSTALLLEVEL is 3, your feature level should be 4. To determine the INSTALLLEVEL value you can check the Property table in your MSI.

Sequencing Components in Feature Element

I want to replace a file that has been installed by my installer. In the following code the "OneCoreFiles" component should install the files first time( which is working) and the component "ConfigCopyFile" should replace that config file.
But the code is not working as expected. The component 'ConfigCopyFile' is getting executed first and then the 'OnecoreFiles'. I want it to work the other way.
I am still learning WIX and thought that the components in Feature elements are executed in the order in which they are declared.
Code Snippet:
<Component Id="ConfigCopyFile" Guid="{98E61055-5A84-4003-90D1-7A67677D7465}">
<Condition>CONFIGFILEEXISTS</Condition>
<CopyFile Id="ConfigFileId" SourceProperty="CONFIGFILEEXISTS" DestinationProperty ="INSTALLDIR"/>
</Component>
<Feature Id="ProductFeature" Title="OneCore Features" Level="1">
<ComponentRef Id="LogEntries" />
<ComponentGroupRef Id="OneCoreFiles" />
<ComponentRef Id="AppDBConfiguration" />
<ComponentRef Id="SqlServerConfiguration" />
<ComponentRef Id="OracleConfiguration" />
<ComponentRef Id="IISConfiguration" />
<ComponentRef Id="ConfigCopyFile" />
</Feature>
This must be quite simple to solve. Am I missing something. Please advice.
You are thinking of WiX in the wrong way. It's not a scripting language. It's a way of representing Windows Installer databases which are declarative in nature not imperative. If I list a bunch of components and files it's non deterministic the order the files will be copied. I'm only saying that these files need to be installed not how to install them.
Windows Installer does expose sequence tables which drive the order of things ( such as create folders then copy files ) but it doesn't micromanage to the level of copy this file before that file.
Suggested InstallExecute Sequence
InstallExecuteSequence Table

How to Select Features From Command Line

This might be a naive question. I have to manually edit a .WXS file to make it support select features from command line.
For example, there are 3 features in .WXS file.
<Feature Id="AllFeature" Level='1'>
<Feature Id="Feature1" Level='1'> </Feature>
<Feature Id="Feature2" Level='1'> </Feature>
<Feature Id="Feature3" Level='1'> </Feature>
</Feature>
Now, I want to select features from command line. Say, if I type "msiexec /i install.msi FEATURE=A", then "Feature1" and "Feature2" is installed; if I type "msiexec/i install.msi FEATURE=B", then "Feature1" and "Feature3" is installed. In this case, "A" maps to Feature 1 and 2; "B" maps to Feature 1 and 3.
How to accomplish this in WIX?
The accepted answer already mentions the ADDLOCAL property, but seems to imply that you can select only one feature. You can actually select multiple features by seperating them by commas like this:
msiexec /i install.msi ADDLOCAL=Feature1,Feature2
or
msiexec /i install.msi ADDLOCAL=Feature2,Feature3
Another hint: you can discover these feature names by opening the msi with orca. This is very useful when you want to use these tricks to create a bootstrapper that installs certain features of thirdparty msi packages.
I would change Feature1, Feature2 and Feature3 to Components, then would declare something like this:
<Feature Id="FEATUREA" Title="Super" Level="1" >
<ComponentRef Id="Component1" />
<ComponentRef Id="Component2" />
</Feature>
<Feature Id="FEATUREB" Title="Super1" Level="1" >
<ComponentRef Id="Component1" />
<ComponentRef Id="Component3"/>
</Feature>
Then to Install either FeatureA or FeatureB
msiexec /i install.msi ADDLOCAL=[FEATUREA | FEATUREB]
There are a number of properties that can control the install states of Features. Check out this MSI SDK documentation and the links from it: http://msdn.microsoft.com/en-us/library/aa367536(VS.85).aspx