I need to define a Wix file component that may not exist in certain circumstances. Is there any way to do this? Condition elements in Wix all seem to work at install time, and I need something that'll detect at compile time if a file is present and build the installer accordingly.
It seems you need to check out the wix preprocessor. Check out wix documentation on the topic: wix preprocessor
for example, suppose you have an environment variable called APPTYPE. If its value is set to 'Full', then MyApp_Full.exe will be included and processed by the wix compiler (candle).
<Component Id='MyComponent1' Guid='fff60f72-5553-4e6b-9bf0-ad62ab9a90b1'>
<?if $(env.APPTYPE) = Full?>
<File Name='MyApp_Full.exe' DiskId='1' Source='..\MyApp_Full.exe' Vital='yes' />
<?endif?>
...
</Component>
There is more! Variables, defines, conditionals. Check out that doc page.
As iwo said, preprocessor variables are your friend! However the example from iwo can (and will) violate component rules, as the component isn't 'stable'. Better to condition an entire component (or component group)...
<?if $(var.releasetype)=full ?>
<ComponentRef Id="Somefile.dll" />
<?elseif $(var.releasetype)=enterprise ?>
<ComponentGroupRef Id="SomethingElse" />
<?endif?>
And then include the Component
and ComponentGroup
s in separate Fragment
tags so that they will only be compiled when referenced :)
<Fragment>
<Component Id="Somefile.dll" Guid="*">
<File Id="Somefile.dll" KeyPath="yes" Source="SourceDir\Somefile.dll" />
</Component>
</Fragment>
<Fragment>
<ComponentGroup Id="SomethingElse">
<ComponentRef Id="Somefile.dll" />
<Component Id="AnotherFile.dll>
<File Id="AnotherFile.dll" KeyPath="yes" Source="SourceDir\AnotherFile.dll" />
</Component>
</ComponentGroup>
</Fragment>
Personally I use nant to call candle
and light
targets, defining different variables for various different builds and products, effective use of fragments and preprocessor variables provides a great opportunity for code re-use between projects, or various releases of the same project.
In your case, to check if a file exists... then you'd just use the internal functions to define, or redefine a variable that is later passed to WiX. e.g.:
<if test="${not file::exists('something.dll')}">
<property name="releasetype" value="blahblahblah" />
</if>