2013-11-25 9 views
9

Sto usando HeatDirectory per creare il file .wxs di origine. Nella directory di prelievo è presente un exe che deve essere installato come servizio. In realtà so come installare il servizio se creo il componente da solo, ma non so come includere ServiceInstall nel componente generato automaticamente. C'è qualche suggerimento?wix HeatDirectory ServiceInstall

 <HeatDirectory DirectoryRefId="Guardian" OutputFile="Source\GuardianSource.wxs" Transforms="Filter.xsl" Directory="..\Setup\C24.Guardian\bin\Debug" PreprocessorVariable="var.GuardianPath" ComponentGroupName="GuardianGroup" ToolPath="$(WixToolPath)" SuppressCom="true" SuppressFragments="true" SuppressRegistry="true" SuppressRootDirectory="true" AutoGenerateGuids="true" GenerateGuidsNow="false"> 
    </HeatDirectory> 



<?xml version="1.0" encoding="utf-8"?> 
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> 
<Fragment> 
    <DirectoryRef Id="Guardian"> 
     <Component Id="cmp70BEDA00F3161F3FB5E847EB1136B1D5" Guid="*"> 
      <File Id="fil26DCBF1E4218C7363018FBA2CD456633" KeyPath="yes" Source="$(var.GuardianPath)\C24.Guardian.exe" /> 
     </Component> 
     <Component Id="cmp2EE8126A193FA022ED35FAD8F182E65A" Guid="*"> 
      <File Id="fil785CD681C496EDDAB457E8314C49D686" KeyPath="yes" Source="$(var.GuardianPath)\C24.Guardian.exe.config" /> 
     </Component> 
     <Component Id="cmp0CC91B457FBC44F978A2AD6B24043DCF" Guid="*"> 
      <File Id="fil2D304D0395599AAAAAF975A2DBFD530F" KeyPath="yes" Source="$(var.GuardianPath)\C24.Guardian.pdb" /> 
     </Component> 
     <Component Id="cmpFB799FA015274DDBE2C337C60667D2C5" Guid="*"> 
      <File Id="filB9C39B394CAD03F5A1BC3262C61EDDEB" KeyPath="yes" Source="$(var.GuardianPath)\C24.Guardian.vshost.exe" /> 
     </Component> 
     <Component Id="cmp28C29865AE85B067BCEEBD70EFDB19D5" Guid="*"> 
      <File Id="fil0A756B711769AAD657F306B3A6EA7134" KeyPath="yes" Source="$(var.GuardianPath)\C24.Guardian.vshost.exe.config" /> 
     </Component> 
     <Component Id="cmp92A715A4BD4B580A6E70362230170428" Guid="*"> 
      <File Id="filBD9D504F303A6EEC9E340E3872BBB0AE" KeyPath="yes" Source="$(var.GuardianPath)\C24.Guardian.vshost.exe.manifest" /> 
     </Component> 
     <Component Id="cmp8AB6A241FA2D13F296CBD946C9711579" Guid="*"> 
      <File Id="fil8EF8CC607CB82B32F84FC9EC2F1636B9" KeyPath="yes" Source="$(var.GuardianPath)\com.Contact24.Tools.dll" /> 
     </Component> 
     <Component Id="cmpC0DBB85C89E8AEA9BAC6E32B85913A2C" Guid="*"> 
      <File Id="fil917CD649C5C318C6717D8EA9FFDF911A" KeyPath="yes" Source="$(var.GuardianPath)\com.Contact24.Tools.pdb" /> 
     </Component> 
     <Component Id="cmp8AFB0FC7CCF571B61196D9166DEEBA24" Guid="*"> 
      <File Id="fil32C12DF0163D5BAD7D0495F2CA2C8DA1" KeyPath="yes" Source="$(var.GuardianPath)\ICSharpCode.SharpZipLib.dll" /> 
     </Component> 
     <Component Id="cmpF5DE5EB2B4C6E33F0C32CFF5F464432C" Guid="*"> 
      <File Id="fil3C8C6F29095A04034E72FBB187F8B841" KeyPath="yes" Source="$(var.GuardianPath)\log4net.dll" /> 
     </Component> 
     <Component Id="cmp27A7791E229DDDBC065069B26138FC2F" Guid="*"> 
      <File Id="fil8DED592D9F63E708FEF848D2980A5186" KeyPath="yes" Source="$(var.GuardianPath)\log4net.xml" /> 
     </Component> 
    </DirectoryRef> 
</Fragment> 
<Fragment> 
    <ComponentGroup Id="GuardianGroup"> 
     <ComponentRef Id="cmp70BEDA00F3161F3FB5E847EB1136B1D5" /> 
     <ComponentRef Id="cmp2EE8126A193FA022ED35FAD8F182E65A" /> 
     <ComponentRef Id="cmp0CC91B457FBC44F978A2AD6B24043DCF" /> 
     <ComponentRef Id="cmpFB799FA015274DDBE2C337C60667D2C5" /> 
     <ComponentRef Id="cmp28C29865AE85B067BCEEBD70EFDB19D5" /> 
     <ComponentRef Id="cmp92A715A4BD4B580A6E70362230170428" /> 
     <ComponentRef Id="cmp8AB6A241FA2D13F296CBD946C9711579" /> 
     <ComponentRef Id="cmpC0DBB85C89E8AEA9BAC6E32B85913A2C" /> 
     <ComponentRef Id="cmp8AFB0FC7CCF571B61196D9166DEEBA24" /> 
     <ComponentRef Id="cmpF5DE5EB2B4C6E33F0C32CFF5F464432C" /> 
     <ComponentRef Id="cmp27A7791E229DDDBC065069B26138FC2F" /> 
    </ComponentGroup> 
</Fragment> 
</Wix> 

Sarà buono per ottenere qualcosa come il seguente codice generato automaticamente:

 <ComponentRef Id="cmp70BEDA00F3161F3FB5E847EB1136B1D5"> 
         <ServiceInstall 
           Id="ServiceAdminGuardianInstaller" 
           Type="ownProcess" 
           Vital="yes" 
           Name="C24.Guardian" 
           DisplayName="C24.Guardian" 
           Description="Служба контроля работы сервера администрирования" 
           Start="auto" 
           Account="[SERVICEACCOUNT]" 
           Password="[SERVICEPASSWORD]" 
           ErrorControl="ignore" 
           Interactive="no"> 

          <util:PermissionEx 
           User="Everyone" 
           GenericAll="yes" 
           ServiceChangeConfig="yes" 
           ServiceEnumerateDependents="yes" 
           ChangePermission="yes" 
           ServiceInterrogate="yes" 
           ServicePauseContinue="yes" 
           ServiceQueryConfig="yes" 
           ServiceQueryStatus="yes" 
           ServiceStart="yes" 
           ServiceStop="yes"/> 

         </ServiceInstall> 

         <ServiceControl Id="StopGuardianService" Name="C24.Guardian" Stop="both" Wait="yes" Remove="uninstall" /> 
     </ComponentRef> 

risposta

8

In alternativa al metodo descritto da @sttaq, quello che faccio di solito è filtrare il. file exe e gestirli manualmente. Stai già filtrando il tuo output di calore con un file xsl (Filter.xsl), quindi dovrebbe essere facile aggiungere una regola per filtrare qualsiasi file * .exe.

<!--Match and ignore .exe files--> 
<xsl:key name="exe-search" match="wix:Component[contains(wix:File/@Source, '.exe')]" use="@Id"/> 
<xsl:template match="wix:Component[key('exe-search', @Id)]"/> 
<xsl:template match="wix:ComponentRef[key('exe-search', @Id)]"/> 

E poi, nel file .wxs, si possono creare manualmente il componente file exe compreso il servizio di installazione, le icone, o qualsiasi cosa potrebbe essere necessario. Basta ricordarsi di metterlo nella giusta Directory:

<Fragment> 
    <DirectoryRef Id="dirA9BC717C5B7BCAAF2B4C1161965AD894"> 
     <Component Id="ExecFileComponent" Guid="YOUR-GUID-HERE"> 
     <RemoveFile Id="RemoveLogFiles" Name="*.svclog" On="both"/> 
     <File Id="ExecFile" Source="$(exefile)" KeyPath="yes" /> 
     <ServiceInstall Id="ServiceInstallation" DisplayName="displayname" Name="name" ErrorControl="normal" Start="auto" Type="ownProcess" Vital="yes"> 
      <util:PermissionEx 
      User="Everyone" 
      GenericAll="yes" 
      ServiceChangeConfig="yes" 
      ServiceEnumerateDependents="yes" 
      ChangePermission="yes" 
      ServiceInterrogate="yes" 
      ServicePauseContinue="yes" 
      ServiceQueryConfig="yes" 
      ServiceQueryStatus="yes" 
      ServiceStart="yes" 
      ServiceStop="yes" /> 
     </ServiceInstall> 
     <ServiceControl Id="ServiceControl" Name="name" Stop="both" Remove="uninstall" /> 
     </Component> 
    </DirectoryRef> 
    </Fragment> 
+0

Soluzione pulita! Sfortunatamente [le variabili non sono consentite] (http://stackoverflow.com/a/8839952/1811525) nell'espressione di corrispondenza, che sarebbe utile per far corrispondere il nome dell'eseguibile completo senza codificarlo nella definizione di trasformazione. :-( – CodeFox

+0

Preferisco la soluzione di sttaq perché è molto utile se stai trasformando il numero di file wxs, passando i parametri. –

5

Suppongo che si conosce già il nome del file che deve essere avvolto in un elemento ServiceInstall.

Questo può essere ottenuto utilizzando la trasformazione xsl. Il processo può essere automatizzato utilizzando l'attività MSBuild XslTransformation. Ecco che cosa ho fatto di recente:

Nel file wixproj nella BeforeBuild bersaglio aggiungere alcuni parametri da passare al xsl, se vi piace potete difficile codificare questi nella vostra XSL e saltare questo passaggio:

<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> 

Poi, dopo il vostro compito HeatDirectory chiamano il compito XslTransformation in questo modo:

<XslTransformation XslInputPath="WixService.xsl" XmlInputPaths="Input.wxs" OutputPaths="Final.wxs" Parameters="$(WixServiceParams)" /> 

aggiungere il file WixService.xsl trasformazione al progetto. Il file è il seguente:

<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> 

una volta fatto il desiderio di un modo migliore di fare questo ...