I'm new to WiX. Very new. Is there a way to define both a ComponentGroup and a Directory at the same time?
I have a large number of files, on the order of 300 or so total, that need to be split into a number of groups, with each group having somewhere around 50 files.
Using heat.exe, I was able to create a Fragment that creates Components for each file. I would like to avoid having to re-list each and every one of these components in a separate ComponentGroup definition. I would love to be able to wrap the list of components generated by heat in a ComponentGroup definition, then simply use that ComponentGroupRef inside of a DirectoryRef structure.
I hope this clears it up. I currently must do:
<DirectoryRef Id="FilesDir">
<Component Id="a.txt" Guid="YOUR-GUID">
<File Id="a.txt" KeyPath="yes" Source="SourceDir\a.txt" />
</Component>
<Component Id="b.txt" Guid="YOUR-GUID">
<File Id="b.txt" KeyPath="yes" Source="SourceDir\b.txt" />
</Component>
...
<Component Id="z.txt" Guid="YOUR-GUID">
<File Id="z.txt" KeyPath="yes" Source="SourceDir\z.txt" />
</Component>
</DirectoryRef>
<ComponentGroup Id="FilesGroup">
<ComponentRef Id="a.txt">
<ComponentRef Id="b.txt">
...
<ComponentRef Id="z.txt">
</ComponentGroup>
I have to list every file twice. That stinks.
I'd like to be able to do:
<ComponentGroup Id="FilesGroup">
<Component Id="a.txt" Guid="YOUR-GUID">
<File Id="a.txt" KeyPath="yes" Source="SourceDir\a.txt" />
</Component>
<Component Id="b.txt" Guid="YOUR-GUID">
<File Id="b.txt" KeyPath="yes" Source="SourceDir\b.txt" />
</Component>
...
<Component Id="z.txt" Guid="YOUR-GUID">
<File Id="z.txt" KeyPath="yes" Source="SourceDir\z.txt" />
</Component>
</ComponentGroup>
<DirectoryRef Id="FilesDir">
<ComponentGroupRef Id="FilesGroup">
</DirectoryRef>
Is that possible? Is there some other way of making this easier that I'm just not seeing?
Update: We abandoned Wix, and therefore I'm not sure if I should mark a solution or not. If someone feels one of the answers below IS the answer to my now-rather-old question, please let me know, and I'll mark the appropriate answer as such.
I hope I understand your question correct. I am using heat tool on every build to autogenerate wxs containing components targetting contents of my build output directory. The WXS (after simplification) looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<ComponentGroup Id="CompGroup01">
<Component Id="cmp1D6110E9A0B9E351095F414BEB4D2E35" Directory="Dir01" Guid="*">
<File Id="fil53541B947C7CE0A96A604898F1B825C5" KeyPath="yes" Source="$(var.HarvestDir)\somefile.exe" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
in the Product.wxs I have this hardcode link to autogenerated code:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="INSTALLDIR" Name="myInstallDir">
<Directory Id="Dir01" Name="myInstallSubDir" />
</Directory>
</Directory>
</Directory>
<Feature Id="ProductFeature" Title="MyProductComplete" Level="1">
<ComponentGroupRef Id="CompGroup01" />
</Feature>
In wixproj file there is a "harvest-task" defined (it is not absolutely clean, but it works). The wixproj is not complete, I deleted all irrelevant parts:
<PropertyGroup>
<!-- relative path to directory from which setup will load input files -->
<MyWixSourceDir>C:\bin</MyWixSourceDir>
<!-- relative path to directory where inputs will be temporarily copied during harvesting -->
<MyWixHarvestDir>tempHarvest</MyWixHarvestDir>
<DefineConstants>Debug;HarvestDirApp=$(ProjectDir)$(MyWixHarvestDir)</DefineConstants>
</PropertyGroup>
<ItemGroup>
<!-- defines item group containing files which represent automatically harvested input for our WiX setup -->
<SetupInputFiles Include="$(MyWixSourceDir)\**\*.*" />
</ItemGroup>
<ItemGroup>
<!-- defines item group of autogenerated files -->
<AutoGeneratedFiles Include="*.autogenerated.wxs" />
</ItemGroup>
<Target Name="BeforeBuild">
<!-- 1) prepare harvesting -->
<!-- remove temporary harvesting directory in case previous build did not cleaned up its temp files and folders -->
<RemoveDir Directories="$(ProjectDir)$(MyWixHarvestDir)" />
<!-- delete old autogenerated files first -->
<Delete Files="@(AutoGeneratedFiles)" ContinueOnError="false" />
<!-- 2) harvest application build output -->
<!-- copies input files into temporary directory so that they can be harvested into WXS file -->
<Copy SourceFiles="@(SetupInputFiles)" DestinationFiles="@(SetupInputFiles->'$(ProjectDir)$(MyWixHarvestDir)\%(RecursiveDir)%(Filename)%(Extension)')" ContinueOnError="false" />
<!-- harvest files and produce WXS file defining all file and directory components for the setup -->
<Exec Command=""$(WixExtDir)heat" dir $(ProjectDir)$(MyWixHarvestDir) -dr Dir01 -sreg -srd -ag -cg CompGroup01 -var var.HarvestDirApp -out InstallDirApp.autogenerated.wxs" ContinueOnError="false" WorkingDirectory="." />
</Target>
<Target Name="AfterBuild">
<!-- 4) clean-up: remove temporary harvesting directory -->
<RemoveDir Directories="$(ProjectDir)$(KbcWixHarvestDir)" />
</Target>
Most important is the Exec element which executes the harvesting. I use "-dr Dir01" to define that components will reference "Dir01" as parent directory and "-cg ComGroup01" to define the componentGroup.
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