I'm using Wix 3.6 beta from the command line, not as VS projects. I have a web application that is harvested with heat as a directory. This works. I'm using web.config transforms to manage each of the target environment web.config files. These are output with msbuild, this works and keeps things visible in Visual Studio and source control.
I've hit a problem deploying one of the several web.config files which I am manually including in product.wxs as components with conditions. I was expecting to include all components as deployable features and let the conditions select just one as active. For example:
<DirectoryRef Id="wwwroot">
<Component Id="setup_a" Guid="some_guid" >
<File Source="$(var.ConfigSourceDir)\setup_a\web.config" />
<Condition>ENVIRON = setup_a</Condition>
</Component>
<Component Id="setup_b" Guid="some_guid" >
<File Source="$(var.ConfigSourceDir)\setup_b\web.config" />
<Condition>ENVIRON = setup_b</Condition>
</Component>
This didn't create any file renaming, moving or deleting issues, but has the very fundamental problem that multiple web.config files are mapped to the same destination and this gives me a light error of "Product.wxs(xxx) : error LGHT0091 : Duplicate symbol 'File:web.config' found. This typically means that an Id is duplicated. Check to make sure all your identifiers of a given type (File, Component, Feature) are unique."
An alternative approach was to use different named .config files and rename/move one to be the web.config, so something like:
<DirectoryRef Id="wwwroot">
<Component Id="setup_a" Guid="some_guid" >
<File Id="setup_a.config" Source="$(var.ConfigSourceDir)\setup_a.config" />
<CopyFile Id="moveit" SourceDirectory="wwwroot" SourceName="setup_a.config" DestinationDirectory="wwwroot" DestinationName="web.config" />
</Component>
This doesn't throw an error, bot the CopyFile command does nothing at all. I just get setup_a.config in the wwwroot folder.
If I nest the CopyFile inside the File, the copy action then works:
<DirectoryRef Id="wwwroot">
<Component Id="setup_a" Guid="some_guid" >
<File Id="setup_a.config" Source="$(var.ConfigSourceDir)\setup_a.config" >
<CopyFile Id="moveit" DestinationName="web.config"/>
</File>
</Component>
...but nested CopyFile means I can't add (it's disallowed) the Delete="yes" attribute to create a 'move' action. Instead I'm left with both setup_a.config and web.config in the wwwroot folder. Alternatively, if I add a seperate removefile within the same component element it also does nothing:
<RemoveFile Id="removefile" On="install" Directory="wwwroot" Name="setup_a.config"/>
</Component>
So, I'm hoping for a working example of how handle multiple web.config files in a conditional deployment, that doesn't leave files behind. the destination filename of web.config is fixed by the framework and can't be changed. The different configs are also pre-generated outside of wix using config transforms, this also can't be changed but the generated filenames could be anything.
cheers!
You complicate it too much. This should work:
<Component Id="setup_a" Guid="some_guid" >
<File Name="web.config" Id="config_a" Source="$(var.ConfigSourceDir)\setup_a\web.config" />
<Condition>ENVIRON = setup_a</Condition>
</Component>
<Component Id="setup_b" Guid="some_guid" >
<File Name="web.config" Id="config_b" Source="$(var.ConfigSourceDir)\setup_b\web.config" />
<Condition>ENVIRON = setup_b</Condition>
</Component>
Pay attention to a couple of things here:
In this sample light will still complain with warning LGHT1076, but that's just a warning - it pays your attention that conditions MUST be mutually exclusive to avoid problems.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With