I have following Wix File that installs the file in Program Files(x86) for 64 bit system and Program Files in 32 bit system. In the program I need to access the file lpa.config that is present in Installed folder, which may be one of two above. For This I need to write the Installed folder in Registry. Is there any way to get the Installed folder location in Wix?
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="CustomWixInstallerWithCustomAction" Language="1033" Version="1.0.0.0" Manufacturer="LogPoint" UpgradeCode="ba9015b9-027f-4451-adb2-e38f9168a850">
<Package InstallerVersion="200" Compressed="no" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="CustomWixInstallerWithCustomAction" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="CustomWixInstaller" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="SomeRandomEXE">
<File Source ="G:\SarVaGYa\myworkspace\LatestLpa\lpa\lpa_c\here\src\lpa\Release\lpa.exe" />
</Component>
<Component Id="registry_values" Guid="{11FB6C4C-3C90-4F46-B0D2-BB95150F60E6}">
<RegistryValue
KeyPath="yes"
Root="HKCU"
Key="Software\Logpoint"
Value="Here I need the path"
Type="string" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
Yes, starting from WiX documentation example:
<DirectoryRef Id="TARGETDIR">
<Component Id="RegistryEntries" Guid="PUT-GUID-HERE">
<RegistryKey Root="HKCU"
Key="Software\Microsoft\MyApplicationName"
Action="createAndRemoveOnUninstall">
<RegistryValue Type="string" Name="SetupPath" Value="PUT-PATH-HERE"/>
</RegistryKey>
</Component>
</DirectoryRef>
WiX is based on Windows Installer and Registry values are Formatted properties, you can use familiar syntax to access properties:
<RegistryValue Type="string" Name="SetupPath" Value="[INSTALLFOLDER]"/>
Property name matches your <Directory> element ID, in your case: <Directory Id="INSTALLFOLDER".
There are other ways to do it but...well IMO this is easiest one.
Related
I have encountered an issue with a VS2017 Project that I am building. For some reason the WiX project is unable to locate the executable and related files. I get the following error message:
The system cannot find the file '......\Bin\Debug\PSALERTSScheduleServer.exe'.
I have checked and the file PSALERTSScheduleServer.exe is definitely in the specified relative folder.
I have used the technique of a defined variable to hold the location of the executable in WiX projects successfully for a number of different projects over the years, however this one is 'bucking the trend'
I am using WiX 3.11. Here is the product.wsx file for the project:
<?xml version="1.0" encoding="UTF-8"?>
<?define SourceDir = "..\..\..\Bin\Debug" ?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Product Id="*" Name="PSALERTSScheduleServerProduct" Language="1033" Version="5.3.0.8" Manufacturer="SP Energy Networks" UpgradeCode="a3baddfc-0965-47ed-a30f-be5eae7bc2df">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="PSALERTS ScheduleServer 2018" Level="1">
<ComponentRef Id="cmpDirScheduleServer" />
<ComponentRef Id="cmpScheduleServerExe" />
<ComponentRef Id="cmpScheduleServerPdb" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="PSALERTSScheduleServerProduct" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<!-- The following section deals with the deployment of the program, config and related data files-->
<Directory Id="ProgramFilesFolder">
<Directory Id="dirSPEnergyNetworks" Name="SP Energy Networks">
<Directory Id="dirPSALERTS" Name="PSALERTS">
<Directory Id="dirScheduleServer" Name="PSALERTS Schedule Server">
<Component Id="cmpDirScheduleServer" Guid="{a valid guid}" KeyPath="yes">
<CreateFolder Directory="dirScheduleServer" />
<RemoveFile Id="PurgeScheduleServer" Name="*.*" On="uninstall" />
<RemoveFolder Id="idDirScheduleServer" On="uninstall" Directory="dirScheduleServer" />
</Component>
<Component Id="cmpScheduleServerExe" Guid="{a valid guid}">
<File Id="filScheduleServerExe"
KeyPath="yes"
Source="$(var.SourceDir)\PSALERTSScheduleServer.exe"
/>
<ServiceInstall Id="cmpScheduleServerExe"
Type="ownProcess"
Name="psaschdsrvr2018"
DisplayName="PSALERTS Schedule Server 2018"
Description="For automatic generation and delivery of PSALERTS reports."
Start="demand"
Account="LocalSystem"
ErrorControl="normal">
<util:PermissionEx
User="Everyone"
ServicePauseContinue="yes"
ServiceQueryStatus="yes"
ServiceStart="yes"
ServiceStop="yes"
ServiceUserDefinedControl="yes"
/>
</ServiceInstall>
<!-- <ServiceControl
Id="cmpScheduleServerExe"
Start="install" Stop="both"
Remove="uninstall"
Name="psaschdsrvr2018"
Wait="yes"
/>-->
<RemoveRegistryKey Id="RemoveScheduleServerRegKey" Root="HKLM" Key="SOFTWARE\SP Energy Networks\PSALERTS\Schedule Server" Action="removeOnUninstall" />
</Component>
<Component Id="cmpScheduleServerPdb" Guid="{a valid guid}">
<File Id="filScheduleServerPdb" KeyPath="yes" Source="$(var.SourceDir)\PSALERTSScheduleServer.pdb" />
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
I'm creating a transform for WiX's heat utility that needs to suppress the harvesting of folders matching a specific name (.PayloadData) under the tree being harvested.
I can easily get it to suppress the Directory and Component elements but the ComponentRef element is proving tricky.
The folder is called .PayloadData and this successfully suppresses the Directory and Component elements:
<xsl:template match="wix:Directory[#Name='.PayloadData']" />
<xsl:template match="wix:Directory[#Name='.PayloadData']/*" />
I tried something similar for the ComponentRef element but it matches everything.
<xsl:template match="wix:ComponentRef[//wix:Directory[#Name='.PayloadData']/wix:Component[#Id=#Id]]">
I think #Id might be ambiguous in the xpath expression but I don't know how to tell it that the ComponentRef's Id attribute is trying to match the Component's Id attribute.
Here's the input:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include $(var.ProjectDir)\..\Common\Common.wxi?>
<Fragment>
<DirectoryRef Id="SampleDataDir">
<Directory Id="dirFD22039A64AC1D31F568C1632B5AF8A3" Name=".PayloadData">
<Component Id="cmp846A29F6413B27E8777DD68E6026E461" Guid="*">
<File Id="fil9227EFCE377E7FEBB63A4BD121F278AE" KeyPath="yes" Source="$(var.SampleDataDir)\.PayloadData\SampleData.xml" />
</Component>
</Directory>
<Directory Id="dirA4E41FB410D214A14F0C8A302E5E70D2" Name="AlternativePBS">
<Component Id="cmp3E04EEF702FDD121FD225ABF32550EDB" Guid="*">
<File Id="filF1367714C6CE3472899C32E78D3D6D0C" KeyPath="yes" Source="$(var.SampleDataDir)\AlternativePBS\01-ADMIN_Update_PBSHierarchy.xml" />
</Component>
<Component Id="cmp6732C6415C5574DB586333DE13FAFD1C" Guid="*">
<File Id="fil7F1A16AA0DA338664312C832796DD228" KeyPath="yes" Source="$(var.SampleDataDir)\AlternativePBS\02-SCHEMA_Update_PBSHierarchy.xml" />
</Component>
<Component Id="cmp01BD73A317794376E5323FA329D1BFEB" Guid="*">
<File Id="filFD2213EB9E67560F25B506695650F7B0" KeyPath="yes" Source="$(var.SampleDataDir)\AlternativePBS\ProcedureForAltPBSStructure.doc" />
</Component>
<Component Id="cmp1E93AAFF75E01670D20E84280E7B9B5C" Guid="*">
<File Id="filC02D64539D33E6B5250C883EFF6357DD" KeyPath="yes" Source="$(var.SampleDataDir)\AlternativePBS\SPFAdapter_PBS.xml" />
</Component>
<Component Id="cmp428BA2587DEE28B22239181E175B108B" Guid="*">
<File Id="fil8D32FED82C161537AE2432BFA7F89310" KeyPath="yes" Source="$(var.SampleDataDir)\AlternativePBS\UpdatePBSHierarchyGraphDef.xmlldr" />
</Component>
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="CG_SampleData">
<ComponentRef Id="cmp846A29F6413B27E8777DD68E6026E461" />
<ComponentRef Id="cmp3E04EEF702FDD121FD225ABF32550EDB" />
<ComponentRef Id="cmp6732C6415C5574DB586333DE13FAFD1C" />
<ComponentRef Id="cmp01BD73A317794376E5323FA329D1BFEB" />
<ComponentRef Id="cmp1E93AAFF75E01670D20E84280E7B9B5C" />
<ComponentRef Id="cmp428BA2587DEE28B22239181E175B108B" />
</ComponentGroup>
</Fragment>
</Wix>
And this is the desired output
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include $(var.ProjectDir)\..\Common\Common.wxi?>
<Fragment>
<DirectoryRef Id="SampleDataDir">
<Directory Id="dirA4E41FB410D214A14F0C8A302E5E70D2" Name="AlternativePBS">
<Component Id="cmp3E04EEF702FDD121FD225ABF32550EDB" Guid="*">
<File Id="filF1367714C6CE3472899C32E78D3D6D0C" KeyPath="yes" Source="$(var.SampleDataDir)\AlternativePBS\01-ADMIN_Update_PBSHierarchy.xml" />
</Component>
<Component Id="cmp6732C6415C5574DB586333DE13FAFD1C" Guid="*">
<File Id="fil7F1A16AA0DA338664312C832796DD228" KeyPath="yes" Source="$(var.SampleDataDir)\AlternativePBS\02-SCHEMA_Update_PBSHierarchy.xml" />
</Component>
<Component Id="cmp01BD73A317794376E5323FA329D1BFEB" Guid="*">
<File Id="filFD2213EB9E67560F25B506695650F7B0" KeyPath="yes" Source="$(var.SampleDataDir)\AlternativePBS\ProcedureForAltPBSStructure.doc" />
</Component>
<Component Id="cmp1E93AAFF75E01670D20E84280E7B9B5C" Guid="*">
<File Id="filC02D64539D33E6B5250C883EFF6357DD" KeyPath="yes" Source="$(var.SampleDataDir)\AlternativePBS\SPFAdapter_PBS.xml" />
</Component>
<Component Id="cmp428BA2587DEE28B22239181E175B108B" Guid="*">
<File Id="fil8D32FED82C161537AE2432BFA7F89310" KeyPath="yes" Source="$(var.SampleDataDir)\AlternativePBS\UpdatePBSHierarchyGraphDef.xmlldr" />
</Component>
</Directory>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="CG_SampleData">
<ComponentRef Id="cmp3E04EEF702FDD121FD225ABF32550EDB" />
<ComponentRef Id="cmp6732C6415C5574DB586333DE13FAFD1C" />
<ComponentRef Id="cmp01BD73A317794376E5323FA329D1BFEB" />
<ComponentRef Id="cmp1E93AAFF75E01670D20E84280E7B9B5C" />
<ComponentRef Id="cmp428BA2587DEE28B22239181E175B108B" />
</ComponentGroup>
</Fragment>
</Wix>
It needs to strip out:
Directory dirFD22039A64AC1D31F568C1632B5AF8A3
Component cmp846A29F6413B27E8777DD68E6026E461
ComponentRef cmp846A29F6413B27E8777DD68E6026E461
Thank you for your help. I now have the answer. Key was the key (pun intended):
<xsl:key name="ComponentsToSuppress" match="wix:Component[ancestor::wix:Directory[#Name='.PayloadData']]" use="#Id" />
<xsl:template match="wix:Directory[#Name='.PayloadData']" />
<xsl:template match="wix:ComponentRef[key('ComponentsToSuppress', #Id)]" />
This allows me to suppress the Component and ComponentRef of items appearing under a Directory named ".PayloadData" regardless of where it appears (or how often it appears).
I have the following snippet of a .wxs(Ids ommitted) outputted from WiX harvest.
<Directory Id="" Name="tr">
<Component Id="" Guid="*">
<File Id="" KeyPath="yes" Source="$(var.SourceDir)\tr\ZedGraph.resources.dll" />
</Component>
</Directory>
<Directory Id="" Name="zh-cn">
<Component Id="" Guid="*">
<File Id="" KeyPath="yes" Source="$(var.SourceDir)\zh-cn\ZedGraph.resources.dll" />
</Component>
</Directory>
<Directory Id="" Name="zh-tw">
<Component Id="" Guid="*">
<File Id="" KeyPath="yes" Source="$(var.SourceDir)\zh-tw\ZedGraph.resources.dll" />
</Component>
</Directory>
</DirectoryRef>
And the following transform will remove the components but leaves the empty directory elements. How can I remove them as well? Given that I do not want to blanket remove all directory elements. Ideally, I would like to match them based on containing the component Id that is returned from the search.
<xsl:key name="zedResource-search" match="wix:Component[contains(wix:File/#Source, 'ZedGraph.resources.dll')]" use="#Id" />
<xsl:template match="wix:Component[key('zedResource-search', #Id)]" />
<xsl:template match="wix:ComponentRef[key('zedResource-search', #Id)]" />
This question is similar, but uses the directory names which i would like to avoid adding a search for each of these because there are quite a few language variants.
One way to do this is use a separate template to match the Directory element where all the child Component elements are in the key. You do this comparison with a count
<xsl:template match="wix:Directory[count(wix:Component)
= count(wix:Component[key('zedResource-search', #Id)])]" />
Alternately, you can say you want to remove Directory which don't have a Component ref that are not in the key (so, a double negative)
<xsl:template match="wix:Directory[not(wix:Component[not(key('zedResource-search', #Id))])]" />
I am developing an IME (Input Method Editor) for Windows so I compiled this sample from microsoft: https://code.msdn.microsoft.com/windowsdesktop/Input-Method-Editor-IME-b1610980/view/Discussions/1 using Visual Studio 2015 and packaged it using WiX.
It installs fine on the computer on which I compiled it, but it seems like I cannot get regsvr32 to register the dll/ime on my other computer (both running windows 10). I get this error
, and manually registering the dll through cmd doesn't work either. My guess is that I am missing a dependency? Does anyone know what I am doing wrong?
Here is the .wxs packaging code from WiX:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="WiXSetup" Language="1033" Version="1.0.0.0" Manufacturer="lwrnc" UpgradeCode="5973bdd3-dea7-4924-a303-4e881386e030">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="WiXSetup" Level="1">
<ComponentGroupRef Id="StartMenuComponents" />
<!--<ComponentGroupRef Id="IMEComponentsx86" />-->
<ComponentGroupRef Id="IMEComponentsx64" />
</Feature>
</Product>
<!--Directory Structure-->
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<!--Start Menu Shortcut-->
<Directory Id="ProgramMenuFolder">
<Directory Id="MyShortcutsDir" Name="WiXSetup">
</Directory>
</Directory>
<!--x86 Version-->
<Directory Id="ProgramFilesFolder">
<Directory Id="IMEINSTALLFOLDERx86" Name="WiXSetup">
</Directory>
</Directory>
<!--x64 Version-->
<Directory Id="ProgramFiles64Folder">
<Directory Id="IMEINSTALLFOLDERx64" Name="WiXSetup">
</Directory>
</Directory>
</Directory>
</Fragment>
<!--Components-->
<Fragment>
<!--x86 IME-->
<!--<ComponentGroup Id="IMEComponentsx86" Directory="IMEINSTALLFOLDERx86">
<Component Id="CMP_IMEx86" Guid="{0CB17F8D-26FF-4E29-A428-710791CDE1EB}">
<File Id="FILE_IMEINSTALLFOLDER_SampleIMEx86DLL" Source="SampleIMEx86.dll" KeyPath="yes" SelfRegCost="1" />
</Component>
<Component Id="CMP_DICTx86" Guid="{66474BE0-ABE5-4B22-8F9B-EB894C6A6218}">
<File Id="FILE_IMEINSTALLFOLDER_SampleIMESimplifiedQuanPinx86TXT" Source="SampleIMESimplifiedQuanPin.txt" KeyPath="yes"/>
</Component>
</ComponentGroup>-->
<!--x64 IME-->
<ComponentGroup Id="IMEComponentsx64" Directory="IMEINSTALLFOLDERx64">
<Component Id="CMP_IMEx64" Guid="{AEDC5FB8-6BB9-4A9F-B920-D6D8244BB837}">
<File Id="FILE_IMEINSTALLFOLDER_SampleIMEx64DLL" Source="SampleIMEx64.dll" KeyPath="yes" SelfRegCost="1" />
</Component>
<Component Id="CMP_DICT" Guid="{C555385F-4848-48B4-90A8-EB0E722605EB}">
<File Id="FILE_IMEINSTALLFOLDER_SampleIMESimplifiedQuanPinx64TXT" Source="SampleIMESimplifiedQuanPin.txt" KeyPath="yes"/>
</Component>
</ComponentGroup>
<!--Start Menu Components-->
<ComponentGroup Id="StartMenuComponents" Directory="MyShortcutsDir">
<Component Id="CMP_DocumentationShortcut" Guid="{4EFD00CD-2297-4A9D-A0A5-47C26897E223}">
<Shortcut Id="WiXSetupDoc" Name="WiXSetup Doc" Description="Read this please" Target="[INSTALLFOLDER]lwrnc.txt" />
<Shortcut Id="UninstallShortcut" Name="Uninstall WS" Description="uninstall wixsetup practice" Target="[System64Folder]msiexec.exe" Arguments="/x [ProductCode]" />
<RemoveFolder Id="RemoveMyShortcutsDir" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\Microsoft\WiXSetup" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
As a part of my WiX installation, I am copying all the transformed/compiled web.config files to the install directory. The names of the compiled web.config are in format web.{ENV}.config. In my install UI I created a Custom Dialog where I parse the ENV and populate a combobox so that the user can select the environment to which we deploy to. This comboBox sets a Property ENV.
I need to understand how i could use this property to copy the installed config files to the website root.
Update: #Rob_Mensching - your solution works, however, on compilation WiX forces me to have a GUID created for each such component. Is there a way I could avoid it? The thing is i am going to generate this piece of code by running XSLT on my wxs file which gets generated using heat; and there is no way I could generate a GUID using XSLT (or can I?)
This is how my code looks now:
<ComponentGroup Id='web.config' Directory='CONFIGLOCATION'>
<Component Id='CopyWebConfigForDev1' Guid='{F207C26A-5D9C-4F19-96A3-D818BB226EFC}' >
<Condition>ENV="Dev1"</Condition>
<CopyFile Id='CopyDev1Config' FileId='fil9C4CFE42035F1A63180142352CF441BC' DestinationDirectory='CONFIGLOCATION' DestinationName='web.config'/>
</Component>
<Component Id='CopyWebConfigForQA1' Guid='{F207C26A-5D9C-4F19-96A3-D818BB226EFC}' >
<Condition>ENV="QA1"</Condition>
<CopyFile Id='CopyQA1Config' FileId='fil12F8B50F03F1BD91A579F6B6CE7195DF' DestinationDirectory='CONFIGLOCATION' DestinationName='web.config'/>
</Component>
</ComponentGroup>
I would use a "Component Condition"b to do so. Something like the following should work well:
<Fragment>
<ComponentGroup Id='web.config' Directory='ConfigFolder'>
<Component>
<Condition>ENV~="Production"</Condition>
<File Source='web.Production.config'>
<CopyFile DestinationDirectory='INSTALLFOLDER' DestinationName='web.config' />
</File>
</Component>
<Component>
<Condition>ENV~="Test"</Condition>
<File Source='web.Test.config'>
<CopyFile DestinationDirectory='INSTALLFOLDER' DestinationName='web.config' />
</File>
</Component>
</ComponentGroup>
</Fragment>
The condition syntax is documented here: http://msdn.microsoft.com/en-us/library/windows/desktop/aa368012(v=vs.85).aspx
With help from the code that Rob provided and after some more research i found out how to avoid having to provide the Guid to each component if your installation folder is not a standard folder. Simply specify the ComponentGuidGenerationSeed for the Custom Directory under which you are trying to install the component to. The directory where you specify this attribute need not be the immediate parent directory of the location where you intend to install the component. This is how my directory structure now looks:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INETPUBFOLDER" Name="inetpub">
<Directory Id="WWWROOTFOLDER" Name="wwwroot" ComponentGuidGenerationSeed="PUT-YOUR-GUID">
<Directory Id="CONFIGLOCATION" Name="$(var.PublishLocation)" />
<Directory Id="INSTALLLOCATION" Name="$(var.PublishLocation)" >
<Directory Id="APPFOLDER" Name="bin" />
<Directory Id="MyProject.Web.Content" />
<Directory Id="CONFIGSFOLDER" Name="Configs">
<Directory Id="WEBFOLDER" Name="Web">
<Directory Id="WEBCONFIGFILES" />
</Directory>
<Directory Id="NLOGFOLDER" Name="NLog">
<Directory Id="NLOGCONFIGFILES" />
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
This is how now my harvested and xml transformed wxs file looks:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="WEBCONFIGFILES">
<Component Id="cmp9CAF0D4A0C62775945002986D1D99926" Guid="PUT-YOUR-GUID">
<File Id="fil9C4CFE42035F1A63180142352CF441BC" KeyPath="yes" Source="$(var.WebConfigFilesDir)\Web.Dev1.config" />
</Component>
<Component Id="cmpB5117E2029EA9A7CC3AFC247EA4483AD" Guid="PUT-YOUR-GUID">
<File Id="fil0F80FEAFAD0333C3B74BB742C4FE118C" KeyPath="yes" Source="$(var.WebConfigFilesDir)\Web.Prod.config" />
</Component>
<Component Id="cmp340743041F12BBE6C7C40D4351407D08" Guid="PUT-YOUR-GUID">
<File Id="fil12F8B50F03F1BD91A579F6B6CE7195DF" KeyPath="yes" Source="$(var.WebConfigFilesDir)\Web.QA1.config" />
</Component>
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="WebConfigFiles">
<ComponentRef Id="cmp9CAF0D4A0C62775945002986D1D99926" />
<ComponentRef Id="cmpB5117E2029EA9A7CC3AFC247EA4483AD" />
<ComponentRef Id="cmp340743041F12BBE6C7C40D4351407D08" />
</ComponentGroup>
</Fragment>
<Fragment>
<UI Id="EnvironmentComboBox">
<ComboBox Property="ENV">
<ListItem Value="Dev1" Text="Dev1" />
<ListItem Value="Prod" Text="Prod" />
<ListItem Value="QA1" Text="QA1" />
</ComboBox>
</UI>
</Fragment>
<Fragment>
<ComponentGroup Id="web.config" Directory="CONFIGLOCATION">
<Component Id="cmpWebConfigForDev1">
<Condition>ENV="Dev1"</Condition>
<File Id="CopyDev1Config" Source="$(var.WebConfigFilesDir)\Web.Dev1.config" Name="web.config" />
</Component>
<Component Id="cmpWebConfigForProd">
<Condition>ENV="Prod"</Condition>
<File Id="CopyProdConfig" Source="$(var.WebConfigFilesDir)\Web.Prod.config" Name="web.config" />
</Component>
<Component Id="cmpWebConfigForQA1">
<Condition>ENV="QA1"</Condition>
<File Id="CopyQA1Config" Source="$(var.WebConfigFilesDir)\Web.QA1.config" Name="web.config" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
In the above file only the first two fragments are generated by the harvest tool. The next two fragments containing the UI/ComboBox Definition and ComponentGroup for WebconfigFiles are created using XML transform by reading the information from File elements in the first Fragment.