I assume that you already know the name of your file that needs to be wrapped in a ServiceInstall
element.
This can be achieved using xsl transformation. The process can be automated using the XslTransformation
MSBuild task. Here is what I have done recently:
In the wixproj
file in the BeforeBuild
target add some parameters to pass on to the xsl, if you like you can hard code these in your xsl and skip this step:
<PropertyGroup>
<WixServiceParams>
<Parameter Name="InstallFolder" Value="INSTALLFOLDER" />
<!-- INSTALLFOLDER is Guardian in your case -->
<Parameter Name="DisplayName" Value="Service Display Name" />
<Parameter Name="Name" Value="ServiceName" />
<Parameter Name="Description" Value="Service Description." />
</WixServiceParams>
<DefineConstants>...</DefineConstants>
</PropertyGroup>
Then after your HeatDirectory task call the XslTransformation task like this:
<XslTransformation XslInputPath="WixService.xsl" XmlInputPaths="Input.wxs" OutputPaths="Final.wxs" Parameters="$(WixServiceParams)" />
Add the WixService.xsl
transformation file to your project. The file is as below:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wix="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="InstallFolder"/>
<xsl:param name="DisplayName"/>
<xsl:param name="Name"/>
<xsl:param name="Description"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- Set Directory Reference to INSTALLFOLDER (set if required) -->
<xsl:template match="wix:DirectoryRef/@Id">
<xsl:attribute name="Id">
<xsl:value-of select="$InstallFolder"/>
</xsl:attribute>
</xsl:template>
<!-- XSL Template to inject WiX service installation elements to a .wxs generated from Heat Project task -->
<!-- There may be other ways to look for your file -->
<xsl:template match='wix:Wix/wix:Fragment/wix:DirectoryRef/wix:Component[wix:File[@Source="PATH-TO\YourService.exe"]]'>
<xsl:element name="wix:Component">
<xsl:attribute name="Id">
<xsl:value-of select="@Id"/>
</xsl:attribute>
<xsl:attribute name="Guid">
<xsl:value-of select="@Guid"/>
</xsl:attribute>
<xsl:element name="wix:File">
<xsl:attribute name="Id">
<xsl:value-of select="wix:File/@Id"/>
</xsl:attribute>
<xsl:attribute name="Source">
<xsl:value-of select="wix:File/@Source"/>
</xsl:attribute>
<xsl:attribute name="KeyPath">yes</xsl:attribute>
</xsl:element>
<xsl:element name="wix:ServiceInstall">
<!-- Service Install -->
<xsl:attribute name="Id">SERVICEINSTALLER</xsl:attribute>
<xsl:attribute name="DisplayName">
<xsl:value-of select="$DisplayName"/>
</xsl:attribute>
<xsl:attribute name="Name">
<xsl:value-of select="$Name"/>
</xsl:attribute>
<xsl:attribute name="Description">
<xsl:value-of select="$Description"/>
</xsl:attribute>
<xsl:attribute name="Start">auto</xsl:attribute>
<xsl:attribute name="Type">ownProcess</xsl:attribute>
<xsl:attribute name="Account">[USERNAME]</xsl:attribute>
<xsl:attribute name="Password">[PASSWORD]</xsl:attribute>
<xsl:attribute name="ErrorControl">normal</xsl:attribute>
<xsl:attribute name="Vital">yes</xsl:attribute>
<!-- Service Dependencies, if required -->
<xsl:element name="wix:ServiceDependency">
<xsl:attribute name="Id">DEPENDENCY</xsl:attribute>
</xsl:element>
<!-- Service Configuration, set as required -->
<xsl:element name="util:ServiceConfig">
<xsl:attribute name="FirstFailureActionType">restart</xsl:attribute>
<xsl:attribute name="SecondFailureActionType">restart</xsl:attribute>
<xsl:attribute name="ThirdFailureActionType">none</xsl:attribute>
<xsl:attribute name="RestartServiceDelayInSeconds">60</xsl:attribute>
</xsl:element>
</xsl:element>
<!-- Service Control, set as required -->
<xsl:element name="wix:ServiceControl">
<xsl:attribute name="Id">SERVICECONTROLLER</xsl:attribute>
<xsl:attribute name="Name">
<xsl:value-of select="$Name"/>
</xsl:attribute>
<xsl:attribute name="Remove">uninstall</xsl:attribute>
<xsl:attribute name="Stop">uninstall</xsl:attribute>
<xsl:attribute name="Wait">no</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
once done wish for a better way of doing this...