问题
So I may not be doing this correct, but here it goes:
I have one application with references to 4 SQL Server assemblies
App must work against SQL 2008 and 2010.
The only way I've gotten this to work is, to have my app reference a 'generic' path for my SQL Assemblies. Then in my MSBuild project, I copy the 2008 assemblies to the 'generic' folder and compile my app. I do this again for the 2012.
I have a folder like Tools\Release\V2008 and Tools\Release\V2010. These folders have all the EXE and required DLLs (including the 4 sql server). I run HEAT against these folders.
However, when I run heat against each folder, with each having the same directory ID but different Component, I get 2 wxs files, each have the same files (expected) but each the component and file ids are identical in the 2 wxs files.
Example:
MSBuild Command:
<Exec Command=""$(WixTools)\heat.exe" dir $(DeploymentRoot)\Tools\V2008 -dr TOOLS -cg Tools2008Component -var var.Tools2008Path -gg -scom -sreg -sfrag -srd -o $(heatOutputPath)\cmp2008ToolsFrag.wxs"/>
WXS File
<DirectoryRef Id="TOOLS">
<Component Id="cmp04831EC1F8BB21C028A7FC875720302F" Guid="*">
<File Id="fil09727A8BFD32FDCE7C743D6DD2008E7C" KeyPath="yes" Source="$(var.Tools2008Path)\AL3Util.exe" />
</Component>
MSBuild Command:
<Exec Command=""$(WixTools)\heat.exe" dir $(DeploymentRoot)\Tools\V2012 -dr TOOLS -cg Tools2012Component -var var.Tools2012Path -gg -scom -sreg -sfrag -srd -o $(heatOutputPath)\cmp2012ToolsFrag.wxs"/>
WXS file
<DirectoryRef Id="TOOLS">
<Component Id="cmp04831EC1F8BB21C028A7FC875720302F" Guid="*">
<File Id="fil09727A8BFD32FDCE7C743D6DD2008E7C" KeyPath="yes" Source="$(var.Tools2012Path)\AL3Util.exe" />
</Component>
How can I get each WXS file to have unique component and file IDs? Or - How can I do this better :)
Thanks!
回答1:
The ID will be the same because you are using -srd
, suppress root directory. In this case, the path used for generating the ID will be only the filename, generating the same ID for files with same name.
You have two alternatives:
1) Use a transform right when you execute heat to harvest the files with -t
.
2) Use XslTransform task (.NET 4) after harvesting to rename the ID to one like File_2012_AL3Util and File_2008_AL3Util.
You can apply this XSL to your file. In the example below, the element will be removed if it matches 'MyFile' for file name and 'MyID' for directory id.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wi="http://schemas.microsoft.com/wix/2006/wi">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- Matches both directory name and file name. -->
<!-- Matches any Component that has its @Directory with same @Id as Directory 'MyID'. -->
<!-- Function ends-with does not work with heat. -->
<xsl:template match="//wi:Component[@Directory=//wi:Directory[@Name='MyID']/@Id and substring(wi:File/@Source, string-length(wi:File/@Source) - string-length('MyFile') + 1) = 'MyFile']" />
</xsl:stylesheet>
来源:https://stackoverflow.com/questions/25813880/wix-harvest-same-component-file-id-when-files-are-in-different-folders