Install features based on checkboxes

12,020

Solution 1

I found what it was that solves my issue. To do as I had intended, I needed to create a checkbox for each feature as so.

<Control Id="FeatureX" Type="CheckBox" X="191" Y="50" Width="140" Height="17"
     Property="FEATUREX_CHECKED" CheckBoxValue="myValue" Text="Install feature X" />
<Control Id="FeatureY" Type="CheckBox" X="191" Y="67" Width="140" Height="17"
     Property="FEATUREY_CHECKED" CheckBoxValue="myValue" Text="Install feature Y" />
<Control Id="FeatureZ" Type="CheckBox" X="191" Y="84" Width="140" Height="17"
     Property="FEATUREZ_CHECKED" CheckBoxValue="myValue" Text="Install feature Z" />

Now once I did that I then added a corresponding publish to each, and made a condition that made it so that only if the check box is selected will that feature be installed. Like so:

<Control Id="Next" Type="PushButton" Text="Next" X="254" Y="243" Height="17" Width="56">
   <Publish Event="Remove" Value="ALL" Order="1">1</Publish>
   <Publish Event="AddLocal" Value="FeatureX" Order="2">
      <![CDATA[FEATUREX_CHECKED]]>
   </Publish>
</Control>

NOTE:

Remove is used to deselect everything from being installed (It was brought to my attention that once the UI is invoked, it is too late to change feature levels).

Then each feature is checked to see if the "corresponding checkbox" has been selected and if so adds it to the "AddLocal" Property. AddLocal would look like this if one were to look at it:

ADDLOCAL=FeatureX, FeatureY, FeatureZ...

The final thing I needed to do to get this to work was too check in my main.wxs to make sure that the FeatureID used in the checkboxes matched up with the ComponentGroupRefID used:

 <ComponentGroupRef Id="FeatureX"/>

So there it is... I again, thank everyone for their help with this. If anyone reading this is confused by anything, please feel free to drop me a line, and I will do my best to explain things a little bit further.

Solution 2

This is my sample code for installing features

Product.wxs

<Product Id="{C9FD5DDE-2625-4E01-B415-8A734464F341}" 
       Name="!(wix.Product)" Language="1033" Version="1.0.0.0" 
       Manufacturer="!(wix.Manufacturer)" UpgradeCode="!(wix.UpgradeCode)">


    <Package InstallerVersion="200" Compressed="yes" Languages="1033"
         Manufacturer="!(wix.Manufacturer)" Description="!(wix.ProductDesc)"/>

    <Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

<WixVariable Id="UpgradeCode" Value="{E5695E2A-EE5F-4EEE-A326-98A9F8B2EF0A}"/>
<WixVariable Id="Manufacturer" Value="BSDreams"/>
<WixVariable Id="Product" Value="WixSubFeatures"/>
<WixVariable Id="ProductDesc" Value="Minimal select one feature install"/>
<WixVariable Id="ProductIcon" Value="chk_on.ico"/>
<WixVariable Id="WixSubFiles" Value=".\Files"/>

<Property Id="ARPNOMODIFY" Value="0" />
<Property Id="ARPPRODUCTICON" Value="!(wix.ProductIcon)" />

<Property Id="INSTALLDIR">
  <RegistrySearch Id="WixSubFeaturesSearch" Type="raw" Root="HKCU"
                  Key="!(wix.Manufacturer)\!(wix.Product)" Name="InstallDir" />
</Property>

<Icon Id="chk_on.ico" SourceFile="!(wix.WixSubFiles)\!(wix.ProductIcon)"/>

    <Directory Id="TARGETDIR" Name="SourceDir">
        <Directory Id="ManufacturerDir" Name="!(wix.Manufacturer)">
            <Directory Id="INSTALLDIR" Name="!(wix.Product)">

      <Component Id="ProductMain" Guid="{FF35C142-480A-4d67-A2ED-E5C9E508F809}">
        <CreateFolder />

        <RegistryKey Id="WixSubDirReg" Root="HKCU" Key="!(wix.Manufacturer)\!(wix.Product)" Action="createAndRemoveOnUninstall">
          <RegistryValue Type="string" Value="[INSTALLDIR]" Action="write"/>
        </RegistryKey>

      </Component>

            </Directory>
        </Directory>
    </Directory>

<UIRef Id="UserInterface"/>

    <Feature Id="PRODUCTFEATURE" Title="!(wix.Product)" Level="1" >
  <ComponentRef Id="ProductMain"/>
  <ComponentRef Id="IconFile"/>
  <Feature Id="OPTIONA" Title="Option A" Level="1" >
    <ComponentRef Id="TestFileA"/>
  </Feature>
  <Feature Id="OPTIONB" Title="Option B" Level="3" >
    <ComponentRef Id="TestFileB"/>
  </Feature>
  <Feature Id="OPTIONC" Title="Option C" Level="3" >
    <ComponentRef Id="TestFileC"/>
  </Feature>

</Feature>


<DirectoryRef Id="INSTALLDIR">
  <Component Id="IconFile" Guid="{967A5110-B0F8-47b0-967B-CC4624D06EA5}">
    <File Id="IconFileA" Source="!(wix.WixSubFiles)\!(wix.ProductIcon)" Name="chk_on.ico" Vital="yes" />
  </Component>

  <Component Id="TestFileA" Guid="{F5ACE3D7-03DE-47a7-9CE8-50CEF5E9A7BF}">
    <File Id="SomeFileA" Source="!(wix.WixSubFiles)\SomeFileA.txt" Name="BSDA.txt" Vital="yes"/>
  </Component>

  <Component Id="TestFileB" Guid="{CB5D53FB-8CED-42ef-89FF-08C7709CFCA5}">
    <File Id="SomeFileB" Source="!(wix.WixSubFiles)\SomeFileB.txt" Name="BSDB.txt" Vital="yes" />
  </Component>

  <Component Id="TestFileC" Guid="{987EA193-A1E0-41d2-8E9D-87D30D8F03AD}">
    <File Id="SomeFileC" Source="!(wix.WixSubFiles)\SomeFileC.txt" Name="BSDC.txt" Vital="yes" />
  </Component>

</DirectoryRef>

<CustomAction Id="SetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLDIR]" />

<InstallExecuteSequence>
  <Custom Action="SetARPINSTALLLOCATION" After="InstallValidate"></Custom>
</InstallExecuteSequence>
</Product>

UserInterface.wxs

<Fragment Id="WixSubUI">
<UI Id="UserInterface">
  <Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
  <Property Id="WixUI_Mode" Value="Custom" />

  <TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
  <TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="9" Bold="yes" />
  <TextStyle Id="WixUI_Font_Title"  FaceName="Tahoma" Size="9" Bold="yes" />

  <Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />

  <DialogRef Id="ProgressDlg" />
  <DialogRef Id="ErrorDlg" />
  <DialogRef Id="FilesInUse" />
  <DialogRef Id="FatalError" />
  <DialogRef Id="UserExit" />
  <DialogRef Id="InstallDirDlg"/>
  <DialogRef Id="FeaturesDlg" />




  <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="FeaturesDlg" Order="2"></Publish>

  <Publish Dialog="FeaturesDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>

  <Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="FeaturesDlg">1</Publish>
  <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
  <Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2">1</Publish>
  <Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1">1</Publish>
  <Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="ExitDialog" Order="2">1</Publish>



  <Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999">1</Publish>

</UI>
<UIRef Id="WixUI_Common" />

This will give you a basic installer that installs base on the selected features checkbox UI

Solution 3

The advice for check boxes is eerily similar to that for radio buttons. Use AddLocal and Remove control events on the Next or Install button, each of which condition against the property tied to your check boxes. It's too late to use feature install levels by the time you're showing UI to the user.

Share:
12,020
Jimmy
Author by

Jimmy

Updated on July 25, 2022

Comments

  • Jimmy
    Jimmy almost 2 years

    I am trying to make it so that when the user selects something via check box, a corresponding feature will be installed.

    I am aware of the prebuilt feature tree that Wix provides but there are some other things that I am doing that do not allow me to use this function. I am curious as to how to link the two together so that when the user selects the check box "Install Feature X", feature X is installed when the user clicks the install button.

    • Jimmy
      Jimmy over 12 years
      I set all of the Levels for each feature to 0, and when the user selects the check box and clicks next I attempt to set the level to 1 with the "Addlocal" property. However other than that I am having a hard time finding alternative solutions. Most the people just revert back to the feature tree
    • Alexey Ivanov
      Alexey Ivanov over 12 years
      The name of the property is ADDLOCAL, all uppercase.
    • Jimmy
      Jimmy over 12 years
      So I made the change from "AddLocal" to "ADDLOCAL" but it did not fix the issue. I am wondering if I am maybe missing something, perhaps I need a property that the when I select the checkbox it set that value and install on condition from there...
  • Jimmy
    Jimmy over 12 years
    I See so in order to do this I would need to do something like this... <Publish Event="AddLocal" Value="FeatureXID">FEATUREX_CHECKED</publish> <Publish Event="Remove" Value="FeatureXID">NOT FEATUREX_CHECKED</publish> Thank you for the responses btw
  • Jimmy
    Jimmy over 12 years
    SO I tried this several different ways and it still did not work...any other ideas that could be posing an issue?
  • sirdank
    sirdank over 9 years
    This causes problems if you want to install silently. Since the button is never clicked nothing is ever removed and everything is always installed. I'm dealing with this right now.
  • sirdank
    sirdank over 9 years
    Still working against the silent install problem. Is there any reason to choose this approach over something like <Feature Id="Feature1" Level="0"> <ComponentGroupRef Id="Components"/> <Condition Level="1">TCP_CHECKBOX_RESULT = "tcp"</Condition> </Feature>?
  • Ven
    Ven over 6 years
    @Jimmy, I am a bit confused. In the AddLocal property, the value should be the Id of the Control or the Id of the Feature? You are showing Id of the Control. Also, how is ComponentGroupRef Id related to AddLocal? Shouldn't it be actually the Feature Id? Please help.
  • hyprsleepy
    hyprsleepy over 6 years
    Is there only one Next button? How does that next button know which feature was checked? I'm not sure I follow how it knows which thing to install.