47
votes

TL;DR: Why do I need an empty <CreateFolder/> element in this conditional component in order to make it work?

I'm putting together a simple WiX based installer for an in-house application. This installer needs to deploy a standard configuration file (a normal .NET .config file) and then customize it using properties passed to msiexec on the command line.

One of the customizations is to create a specific application setting only if the RUNTIME property has been defined. Here's the WiX component for that:

  <Component Id="C.Rbnz.Fsis.CollectionPeriodService.exe.config.runtime"
             Guid="*">
    <Condition>
      <![CDATA[RUNTIME]]>
    </Condition>

    <CreateFolder/>

    <util:XmlFile Id="X.Runtime.1"
                  Action="createElement"
                  ElementPath="/configuration/appSettings"
                  File="[#F.Rbnz.Fsis.CollectionPeriodService.exe.config]"
                  Name="add"
                  Sequence="2"/>

    <util:XmlFile Id="X.Runtime.2"
                  File="[#F.Rbnz.Fsis.CollectionPeriodService.exe.config]"
                  ElementPath="/configuration/appSettings/add[\[]not(@key)[\]]"
                  Action="setValue"
                  Name="key"
                  Value="RunTime"
                  Sequence="3"/>

    <util:XmlFile Id="X.Runtime.3"
                  File="[#F.Rbnz.Fsis.CollectionPeriodService.exe.config]"
                  ElementPath="/configuration/appSettings/add[\[]@key='RunTime'[\]]"
                  Action="setValue"
                  Name="value"
                  Value="[RUNTIME]"
                  Sequence="4"/>

  </Component>

This works just as I want - if RUNTIME is specified on the commandline for msiexec, the new element gets created; if not, nothing happens.

Why do I have to have the empty <CreateFolder/> within this component?

While I was trying to get this working, I found "Wix Condition Statement", which showed a working component, but doesn't explain why <CreateFolder/> is necessary.

Removing <CreateFolder/> gives me this error:

ICE18: KeyPath for Component: 'C.Rbnz.Fsis.CollectionPeriodService.exe.config.runtime' is Directory: 'INSTALLDIR'. The Directory/Component pair must be listed in the CreateFolders table.

which is, I'm sure, quite informative once you know what it means.

2

2 Answers

49
votes

Every component has a key path; the most common is a file. Your component doesn't have a file or other key path, so WiX gives it the default of a directory. Windows Installer then comes along and says that components with directory key paths must ensure the directory is created, even if something else will do so. It's a silly rule with an easy fix.

21
votes

You can use the parametre KeyPath="yes" in your component tag instead. Only if the 'INSTALLDIR' is the correct path for this component.