使用WiX安装.NET Core 3.0的工作服务为Windows服务

8

随着.NET Core 3的新版本发布,我正在尝试使用新的工作服务模板创建Windows服务。我需要能够通过组策略进行安装,而WiX似乎是这项工作的工具。

我已经创建了.wxs文件,如果不指定ServiceInstall部分,它可以正常安装。

以下是我的文件:已更新

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="*" Name="SystemInformationService" Language="1033" Version="1.0.0.0" Manufacturer="MyCompany" UpgradeCode="f08191cf-461e-481b-a2a1-6f54d6ae5331">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />

    <!-- Embed cab files, don't include them in the output -->
    <MediaTemplate EmbedCab="yes"/>

    <!-- Default WiX dialog set -->
    <UIRef Id="WixUI_Mondo" />

    <!-- License agreement -->
    <WixVariable Id="WixUILicenseRtf" Value="LicenseAgreement.rtf" />

    <Feature Id="ProductFeature" Title="SystemInformationService.Setup" Level="1">
      <ComponentGroupRef Id="ProductComponents" />
      <ComponentGroupRef Id="HeatGenerated" />
    </Feature>
  </Product>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLFOLDER" Name="SystemInformationService" />
      </Directory>
    </Directory>
  </Fragment>

  <Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
      <!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
      <Component Id="ProductComponent" Guid="5BB7300D-C29F-4C87-B461-AAE3AA4EB56D">
        <CreateFolder/>
        <!--<File Source="$(var.SystemInformationService.TargetPath)" />-->
        <ServiceInstall
          Id="ServiceInstaller"
          Type="ownProcess"
          Name="SystemInformationService"
          DisplayName="System Information Service"
          Description="System Information service by MyCompany"
          Start="auto"
          Vital="no"
          Account="LocalSystem"
          Interactive="no"
          ErrorControl="normal" />
        <ServiceControl
          Id="ServiceInstaller"
          Start="install"
          Stop="both"
          Remove="uninstall"
          Name="SystemInformationService"
          Wait="yes" />
      </Component>
    </ComponentGroup>
  </Fragment>
</Wix>

现在我正在尝试添加服务组件,以便在安装时启动。当我添加后运行安装程序时,安装程序UI停留在“Starting Service...”上。我尝试添加了“start”参数,因为我在另一个答案中看到了这个。
我想如果这是.net core,我可能需要添加一个操作.exe或类似的东西来启动服务。这是我所能想到的 - 任何建议都会有所帮助。
谢谢
更新:我已经更新了.wxs文件到我现在拥有的内容,并且我已经使用框架依赖部署正确地进行了安装。我的问题是指定了AnyCPU而不是x86。但是......现在当我切换到自包含的部署时,我得到了与以前相同的错误。所以这一定与我如何发布.net core有关。
这是我当前的发布配置文件。当我切换到框架依赖项时,安装程序正常运行并启动服务。

1
以下是一些链接:调试思路列表依赖扫描服务调试 - Stein Åsmul
谢谢Stein,我发现如果我使用框架相关的方式,它可以在我的电脑上运行(因为我显然已经安装了.NET Core),但是当我切换到自包含的方式时,它又失败了(即使在我的电脑上)。 - aweyeahdawg
我从未编写过 .net core 的 Windows 服务,因此问题就来了:.NET Core 是否像 .NET 的 ServiceBase 一样创建 Windows 服务,可以响应 ServiceStart 和 ServiceStop 事件,还是基本上只是作为工作程序运行的控制台应用程序?如果答案是后者,那么您需要使用类似 SrvAny 或 NSSM 的东西作为托管层。 - Christopher Painter
是的,克里斯,我也这么想。现在没有时间查看,但以下是一些参考链接:在Windows服务中托管ASP.NET Core.NET Core应用程序部署 - Stein Åsmul
1
你愿意尝试一下我为此准备的开源项目吗?请按照“Windows服务”教程操作,但使用.NET Core而不是.NET Framework来创建您的服务,并查看是否一切正常。根据您上次评论中提供的链接,我认为应该可以实现。https://github.com/iswix-llc/iswix-tutorials - Christopher Painter
显示剩余3条评论
1个回答

5

问题解决了。我的问题在于服务的.exe文件必须定义在.wxs中的'ServiceInstall'和'ServiceControl'标签之上。所以我需要做的是创建一个过滤器.xslt来过滤掉热生成文件中的.exe文件,然后在Service组件(keypath='yes')上方添加一个标记,位于ServiceInstall之上。

以下是我的最终.wxs和.xslt文件。

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="*" Name="SystemInformationService" Language="1033" Version="1.0.2.0" Manufacturer="MyCompany" UpgradeCode="f08191cf-461e-481b-a2a1-6f54d6ae5331">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    <Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
    <Upgrade Id="f08191cf-461e-481b-a2a1-6f54d6ae5331">
      <UpgradeVersion
         Minimum="1.0.0" Maximum="99.0.0"
         Property="PREVIOUSVERSIONSINSTALLED"
         IncludeMinimum="yes" IncludeMaximum="no" />
    </Upgrade>
    <MajorUpgrade DowngradeErrorMessage="A newer version of System Information Service is already installed." />

    <!-- Embed cab files, don't include them in the output -->
    <MediaTemplate EmbedCab="yes"/>

    <!-- Default WiX dialog set -->
    <UIRef Id="WixUI_Minimal" />

    <!-- License agreement -->
    <WixVariable Id="WixUILicenseRtf" Value="LicenseAgreement.rtf" />

    <Feature Id="ProductFeature" Title="SystemInformationService.Setup" Level="1">
      <ComponentGroupRef Id="ProductComponents" />
      <ComponentGroupRef Id="HeatGenerated" />
    </Feature>

    <!--<CustomAction Id="installService" Directory="INSTALLFOLDER" Execute="commit" ExeCommand="sc create SystemInformationService binPath=INSTALLFOLDER/SystemInformationService.exe" Return='ignore'/>
    <CustomAction Id="testAction" Directory="INSTALLFOLDER" Execute="commit" ExeCommand="notepad.exe test.txt" Return='ignore'/>
    <CustomAction Id="startService" Directory="INSTALLFOLDER" Execute="commit" ExeCommand="sc start binPath=INSTALLFOLDER/SystemInformationService.exe" Return='ignore'/>-->

  </Product>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLFOLDER" Name="SystemInformationService" />
      </Directory>
    </Directory>
  </Fragment>

  <Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
      <!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
      <Component Id="ProductComponent" Guid="5BB7300D-C29F-4C87-B461-AAE3AA4EB56D">
        <!--<File Source="$(var.SystemInformationService.TargetPath)" />-->
        <!--<CreateFolder/>-->
        <File Id="SystemInformationService" KeyPath="yes" Source="..\SystemInformationService\bin\Release\netcoreapp3.0\win-x86\SystemInformationService.exe"/>
        <ServiceInstall
          Id="ServiceInstaller"
          Type="ownProcess"
          Name="SystemInformationService"
          DisplayName="System Information Service"
          Description="System Information service by MyCompany"
          Start="auto"
          Account="LocalSystem"
          ErrorControl="normal" />
        <ServiceControl
          Id="ServiceInstaller"
          Start="install"
          Stop="both"
          Remove="uninstall"
          Name="SystemInformationService"
          Wait="yes" />
      </Component>
    </ComponentGroup>
  </Fragment>
</Wix>


<?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:util="http://schemas.microsoft.com/wix/UtilExtension">

  <xsl:output method="xml" indent="yes" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:key name="exe-search" match="wix:Component[contains(wix:File/@Source, 'SystemInformationService.exe')]" use="@Id" />

  <xsl:template match="wix:Component[key('exe-search', @Id)]" />
  <xsl:template match="wix:ComponentRef[key('exe-search', @Id)]" />

</xsl:stylesheet>

1
请问您能分享一下您用于此的XSLT吗? - Hari Pachuveetil
1
@HariPachuveetil 很抱歉回复晚了。我已经更新了我的答案并添加了过滤器。 - aweyeahdawg
我找到了另一个答案,它具有非常相似的XSLT - 但谢谢! :) - Hari Pachuveetil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接