2013-11-25 10 views
9

Tôi đang sử dụng HeatDirectory để tạo tệp .wxs nguồn. Trong thư mục pickup có một exe cần được cài đặt như dịch vụ. Trên thực tế tôi biết làm thế nào để cài đặt dịch vụ nếu tôi tạo thành phần bản thân mình, nhưng tôi không biết làm thế nào để bao gồm ServiceInstall trong thành phần tự động tạo ra. Có gợi ý nào không?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> 

Nó sẽ được tốt để có được một cái gì đó giống như các mã tự động sau tạo:

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

Trả lời

8

Để thay thế cho phương pháp mô tả bởi @sttaq, những gì tôi thường làm là lọc ra. exe tập tin và quản lý chúng bằng tay. Bạn đã lọc đầu ra nhiệt của mình bằng một tệp xsl (Filter.xsl), do đó, nên dễ dàng thêm quy tắc để lọc ra bất kỳ tệp * .exe nào.

<!--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)]"/> 

Sau đó, trong tệp .wxs, bạn có thể tự tạo thành phần tệp .exe bao gồm trình cài đặt dịch vụ, biểu tượng hoặc bất kỳ thứ gì bạn có thể cần. Chỉ cần nhớ đặt nó vào bên phải Thư mục:

<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

Giải pháp gọn gàng! Thật không may [biến không được phép] (trong http://stackoverflow.com/a/8839952/1811525) trong biểu thức khớp, mà sẽ có ích để khớp với tên của tệp thực thi đầy đủ mà không cần mã hóa cứng nó trong định nghĩa chuyển đổi. :-( – CodeFox

+0

Tôi thích giải pháp của sttaq vì nó rất hữu ích nếu bạn đang chuyển đổi số tệp wxs, bằng cách truyền tham số. –

5

Tôi giả định rằng bạn đã biết tên của tập tin của bạn mà cần phải được bao bọc trong một phần tử ServiceInstall.

Điều này có thể đạt được bằng cách sử dụng phép chuyển đổi xsl. Quá trình có thể được tự động bằng cách sử dụng nhiệm vụ MSBuild XslTransformation. Dưới đây là những gì tôi đã làm gần đây:

Trong wixproj tập tin trong mục tiêu BeforeBuild thêm một số thông số để truyền lại cho các xsl, nếu bạn thích, bạn khó có thể mã này trong xsl của bạn và bỏ qua bước này:

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

sau đó, sau khi nhiệm vụ HeatDirectory bạn gọi nhiệm vụ XslTransformation như thế này:

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

Thêm tập tin WixService.xsl chuyển đổi để dự án của bạn. Các tập tin như sau:

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

một lần thực hiện ước nguyện cho một cách tốt hơn để làm điều này ...