问题
While harvesting files for heat.exe, I would like to exclude the files with the extension .exe from the input folder since it fetches all the files in the folder at first place.
Below is my code.
"%WIX_PATH%\Heat.exe" dir "%input_folder%" -cg SourceProjectComponents -dr INSTALLLOCATION -scom -sreg -srd -var var.BasePath -gg -sfrag -var var.BasePath -out "%output_folder%\Output.wxs"
PS: the input_folder consists of severall .dll and .exe files. hence individual harvesting of the file wasn't possible.
Thanks in advance.
回答1:
You will need to use an XSLT transform.
Something like this should work for you; Just include -t <Path to the xslt file>
in your command line for heat.
This XSLT outputs a new XML file that contains all XML nodes of the input, except if any nodes are <Component>
elements with .exe
<File>
elements.
RemoveExeComponentsTransform.xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
xmlns="http://schemas.microsoft.com/wix/2006/wi"
version="1.0"
exclude-result-prefixes="xsl wix"
>
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<!--
Find all <Component> elements with <File> elements with Source="" attributes ending in ".exe" and tag it with the "ExeToRemove" key.
<Component Id="cmpSYYKP6B1M7WSD5KLEQ7PZW4YLOPYG61L" Directory="INSTALLDIR" Guid="*">
<File Id="filKUS7ZRMJ0AOKDU6ATYY6IRUSR2ECPDFO" KeyPath="yes" Source="!(wix.StagingAreaPath)\ProofOfPEqualsNP.exe" />
</Component>
Because WiX's Heat.exe only supports XSLT 1.0 and not XSLT 2.0 we cannot use `ends-with( haystack, needle )` (e.g. `ends-with( wix:File/@Source, '.exe' )`...
...but we can use this longer `substring` expression instead (see https://github.com/wixtoolset/issues/issues/5609 )
-->
<xsl:key
name="ExeToRemove"
match="wix:Component[ substring( wix:File/@Source, string-length( wix:File/@Source ) - 3 ) = '.exe' ]"
use="@Id"
/> <!-- Get the last 4 characters of a string using `substring( s, len(s) - 3 )`, it uses -3 and not -4 because XSLT uses 1-based indexes, not 0-based indexes. -->
<!-- We can also remove .pdb files too, for example: -->
<xsl:key
name="PdbToRemove"
match="wix:Component[ substring( wix:File/@Source, string-length( wix:File/@Source ) - 3 ) = '.pdb' ]"
use="@Id"
/>
<!-- By default, copy all elements and nodes into the output... -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<!-- ...but if the element has the "ExeToRemove" key then don't render anything (i.e. removing it from the output) -->
<xsl:template match="*[ self::wix:Component or self::wix:ComponentRef ][ key( 'ExeToRemove', @Id ) ]" />
<xsl:template match="*[ self::wix:Component or self::wix:ComponentRef ][ key( 'PdbToRemove', @Id ) ]" />
</xsl:stylesheet>
回答2:
I had the same issue where I had lots of files that I needed to include into the WXS file in a project and I wrote an open source command line application to generate XMLs of directory structure, files and components while ignoring folders, extensions, files etc via a .wixignore file (formatted similar to .gitignore).
You can take a look at the it here.
回答3:
If you’re using WiX toolset 4.0:
The xsl filters won't work until you set the correct namespace (xmlns:wix="http://wixtoolset.org/schemas/v4/wxs"
)
I've been in the situation of upgrading from 3.11 to 4.0 and it took me hours to find out why the filter simply didn't work. Either in VS solution nor in command line (heat.exe) version.
Hope this helps someone
来源:https://stackoverflow.com/questions/44765707/how-to-exclude-files-in-wix-toolset