Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I require at least one of two optional components in WiX?

I am using WixUIFeatureTree to offer the user an option of what components of my application they want to install... One of my features has two optional features within it, at least one of which must be installed for the program to work. I don't want to force the user to install either particular one, but I'm at a loss as to how to force them to choose at least one.

Here's the relevant portion of my current WXS:

    <Feature Id="Main" Title="Product Name" Level="1" Absent="disallow" Display="expand" AllowAdvertise="no"
             Description="This is the application, and is a required component"
             >
        <ComponentRef Id="Baseline" />
        <ComponentRef Id="Shortcuts" />
        <Feature Id="Option1" Title="Plugin #1" Level="2" Absent="allow" AllowAdvertise="no">
            <ComponentRef Id="Plugin1Component" />
        </Feature>
        <Feature Id="Option2" Title="Plugin #2" Level="3" Absent="allow" AllowAdvertise="no">
            <ComponentRef Id="Plugin2Component" />
        </Feature>
    </Feature>

I'm guessing that I'm going to need some kind of Custom Action inserted at the right point of the sequence guaranteeing that one or the other is selected for install, but no clue how to do that, or if it's even right. All help appreciated!

like image 249
Michael Bray Avatar asked Sep 02 '09 01:09

Michael Bray


People also ask

What are WiX components?

A WiX component is a container for files, registry keys, and other resources that are installed on a user's computer. A component can be shared by multiple features, or it can be used by a single feature. WiX components are identified by unique GUIDs.


3 Answers

I realize this is an old post, but this is how I solved this using WIX v3.7 with the UI FeatureTree:

<Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">&amp;MyAppClientFeature=3 OR &amp;MyAppPrinterFeature=3</Publish>

Full FeatureTree override code:

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

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

    <DialogRef Id="ErrorDlg" />
    <DialogRef Id="FatalError" />
    <DialogRef Id="FilesInUse" />
    <DialogRef Id="MsiRMFilesInUse" />
    <DialogRef Id="PrepareDlg" />
    <DialogRef Id="ProgressDlg" />
    <DialogRef Id="ResumeDlg" />
    <DialogRef Id="UserExit" />

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

    <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="LicenseAgreementDlg">NOT Installed</Publish>
    <Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">Installed AND PATCH</Publish>

    <Publish Dialog="LicenseAgreementDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg">1</Publish>
    <Publish Dialog="LicenseAgreementDlg" Control="Next" Event="NewDialog" Value="CustomizeDlg">LicenseAccepted = "1"</Publish>

    <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="1">Installed</Publish>
    <Publish Dialog="CustomizeDlg" Control="Back" Event="NewDialog" Value="LicenseAgreementDlg" Order="2">NOT Installed</Publish>
    <Publish Dialog="CustomizeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg">&amp;MyAppClientFeature=3 OR &amp;MyAppPrinterFeature=3</Publish>

    <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="CustomizeDlg" Order="1">NOT Installed OR WixUI_InstallMode = "Change"</Publish>
    <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2">Installed AND NOT PATCH</Publish>
    <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="3">Installed AND PATCH</Publish>

    <Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg">1</Publish>

    <Publish Dialog="MaintenanceTypeDlg" Control="ChangeButton" Event="NewDialog" Value="CustomizeDlg">1</Publish>
    <Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
    <Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
    <Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg">1</Publish>
</UI>

<UIRef Id="WixUI_Common" />

I hope this helps someone out.

like image 122
Adam Plocher Avatar answered Sep 16 '22 12:09

Adam Plocher


I think what you actually want to do here is put a condition in the <Publish> element for the Next button to not enable it until your conditions are met. Something like:

<Publish Dialog="..." Control="Next" Event="NewDialog" Value="...">OptionalPkg1Selected OR OptionaloPkg2Selected</Publish>

What I don't know is how to set those conditions based on which components are checked, though there has to be some way to do it so that the right components get installed later on...

like image 31
i_am_jorf Avatar answered Sep 19 '22 12:09

i_am_jorf


How about using the Feature state as a condition?

Something like (&Option1=2) AND (&Option2=2)

Here is a link for better understanding:

MSI Advanced Custom Actions

like image 36
Gabriel Avatar answered Sep 18 '22 12:09

Gabriel