wix - Move from manual component creation to harvesting with the HeatDirectory task -
i using wix 3.8 build project installs product. installer done. 1 of programmes gets installed package relying on dlls third party updated frequently. idiotically version number of dlls change on regular basis. when first writing installer project did not consider inculding support changing file names , wrote every component manually.
this behaviour should changed in future. if understand correctly, generating components files automatically can done of heatdirectory task. have created example project using heatdirectory task working. there discrepancy in output heatdirectory task produces , manually authored components have been using in past.
i heatdirectory task produce same output manual approach, possible. following code of 2 components, first created manually , secondly created heatdirectory task:
manually created components:
<componentgroup id="thirdparty.v13.2" directory="installfolder"> <component id="cmp_thirdparty.v13.2.dll" guid="ac5e00f0-b458-4272-b132-f13594ed4916"> <file id="thirdparty.v13.2.dll" name="thirdparty.v13.2.dll" source="componentsdir\thirdparty\thirdparty.v13.2.dll" keypath="yes" assembly=".net" assemblyapplication="thirdparty.v13.2.dll" assemblymanifest="thirdparty.v13.2.dll" compressed="no" diskid="$(var.thirdpartydiskid)"/> </component> <component id="cmp_thirdparty.v13.2.xml" guid="64ac3f5f-38e9-41ec-b714-636f5d9c0cb4"> <file id="thirdparty.v13.2.xml" name="thirdparty.v13.2.xml" source="source="componentsdir\thirdparty\thirdparty.v13.2.xml" keypath="yes" compressed="no" diskid="$(var.thirdpartydiskid)"/> </component> </componentgroup>
heatdirectory task generated code:
<componentgroup id="files"> <component id="cmp9d064a733360960e07277cfd9ab84af1" directory="installfolder" guid="*"> <file id="fild5dcb6e091d2d12303e2e80b0b767438" keypath="yes" source="$(var.path)\thirdparty.v13.2.dll"/> </component> <component id="cmpa8681a63a8a4991d18824ba17e4ca4bf" directory="installfolder" guid="*"> <file id="fil17554b3cd0e576337aec758831009938" keypath="yes" source="$(var.path)\thirdparty.v13.2.xml"/> </component> </componentgroup>
the code producing output above following:
<target name="beforebuild"> <heatdirectory directoryrefid="installfolder" outputfile="files.wxs" directory="s:\omepath" suppressrootdirectory="true" toolpath="$(wixtoolpath)" autogenerateguids="true" componentgroupname="files" preprocessorvariable="var.path"> </heatdirectory> </target>
i'll note down characteristics of heatdirectory task generated code i'd change:
- every component in componentgroup has
directory
attribute. want parentcomponentgroup
havedirectory
attribute , omit in every child component. - i want static guids.
- i want component's
id
attribute composed of prefixcmp
followed file name. understand there cannot 2 files having same file name in project know not case. don't want cryptic identifier generated task. - the
file
child item of component spartanic. want heatdirectoy task createname
attribute every file current name of file.compressed
attribute should added valueno
,diksid
should added variable value can specified in task somehow. - if harvested file dll, task should append attributes
asssembly
value.net
,assemblyapplication
name of harvested file value &assemblymanifest
name of harvested file value.
is possible achieve heatdirectory task?
the answer manipulating output of heatdirectory task use xslt. in heatdirectory task attribute called transforms
can specified points file containing xslt instructions. achieve output asking for, following xslt code can used:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> <xsl:output method="xml" indent="yes"/> <xsl:variable name="componentgroup-id" select="//wix:componentgroup/@id"/> <xsl:variable name="destinationfolder" select="//wix:component[1]/@directory"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select ="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="//wix:directory"> <xsl:variable name="dirname" select="@name" /> <xsl:copy> <xsl:attribute name="id"> <xsl:value-of select="$componentgroup-id"/> <xsl:text>_</xsl:text> <xsl:value-of select="$dirname"/> </xsl:attribute> <xsl:attribute name="name"> <xsl:value-of select="$dirname"/> </xsl:attribute> </xsl:copy> </xsl:template> <xsl:template match="//wix:componentgroup"> <xsl:copy> <xsl:attribute name="id"> <xsl:value-of select="$componentgroup-id"/> </xsl:attribute> <xsl:attribute name="directory"> <xsl:value-of select="$destinationfolder"/> </xsl:attribute> <xsl:apply-templates /> </xsl:copy> </xsl:template> <xsl:template match="//wix:component"> <xsl:variable name="filepath" select="current()/wix:file/@source" /> <xsl:variable name="filename" select="substring-after($filepath,'\')" /> <xsl:variable name="guid" select="@guid" /> <xsl:copy> <xsl:attribute name="id"> <xsl:text>cmp_</xsl:text> <xsl:choose> <xsl:when test="contains($filename,'\')"> <xsl:value-of select="substring-after($filename,'\')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$filename"/> </xsl:otherwise> </xsl:choose> </xsl:attribute> <xsl:attribute name="guid"> <xsl:value-of select="$guid"/> </xsl:attribute> <xsl:apply-templates /> </xsl:copy> </xsl:template> <xsl:template match="//wix:file"> <xsl:variable name="filepath" select="@source" /> <xsl:variable name="filename" select="substring-after($filepath,'\')" /> <xsl:copy> <xsl:attribute name="id"> <xsl:choose> <xsl:when test="contains($filename,'\')"> <xsl:value-of select="substring-after($filename,'\')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$filename"/> </xsl:otherwise> </xsl:choose> </xsl:attribute> <xsl:attribute name="keypath"> <xsl:text>yes</xsl:text> </xsl:attribute> <xsl:attribute name="source"> <xsl:value-of select="$filepath"/> </xsl:attribute> <xsl:if test="contains($filename,'.dll')"> <xsl:attribute name="assembly">.net</xsl:attribute> <xsl:attribute name="assemblyapplication"> <xsl:choose> <xsl:when test="contains($filename,'\')"> <xsl:value-of select="substring-after($filename,'\')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$filename"/> </xsl:otherwise> </xsl:choose> </xsl:attribute> <xsl:attribute name="assemblymanifest"> <xsl:choose> <xsl:when test="contains($filename,'\')"> <xsl:value-of select="substring-after($filename,'\')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$filename"/> </xsl:otherwise> </xsl:choose> </xsl:attribute> </xsl:if> <xsl:attribute name="compressed"> <xsl:text>no</xsl:text> </xsl:attribute> <xsl:attribute name="diskid"> <xsl:text>$(var.somediskid)</xsl:text> </xsl:attribute> </xsl:copy> </xsl:template> </xsl:stylesheet>
Comments
Post a Comment