Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Install .NET Core 3.0 Worker Service with WiX as Windows Service

Tags:

c#

.net-core

wix

With the new release of .NET Core 3, I am trying to make a windows service with the new worker service template. I need to be able to install this with group policy, and WiX seems to be the tool for the job.

I've created the .wxs file and without specifying the ServiceInstall section, it installs fine.

Here's my file: UPDATED

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

Now I'm trying to add the service components so that it will start on install. When I run the installer after adding it, the installer UI hangs on 'Starting Service...'. I tried adding the 'start' arguments since I saw that on another answer.

I'm thinking since this is .net core, I might need to add an action .exe or something to start the service. That's all I can think of - any suggestions will help.

Thanks

UPDATE: I've updated the .wxs file to what I now have, and I have it correctly installing with a framework dependent deployment. My problem was specifying AnyCPU instead of x86. But... Now when I switch to a self-contained deployment I get the same error as before. So It must be something to do with how I'm publishing the .net core.

This is my publish profile currently. When i switch to framework dependent the installer runs fine and starts the service. This is my publish profile currently. When i switch to framework dependent the installer runs fine and starts the service.

like image 356
aweyeahdawg Avatar asked Sep 24 '19 15:09

aweyeahdawg


People also ask

How do you deploy a Windows service to a production server?

Answers. You can add a installer class to your project, and the add your project outputs to a setup project, then you can use this installer install your windows service. For more details you can look into the steps in the MSDN document.

What is .NET core worker service?

Worker Services were introduced in . NET Core 3.0, and allows for running background services through the use of a hosted service. Another way of running background services is to run hosted services within an ASP.NET Core web application.


1 Answers

Figured it out. What I was missing was the .exe of the service must be defined above the 'ServiceInstall' and 'ServiceControl' tags in the .wxs. So what I needed to do was create a filter .xslt to filter the .exe out of the heat generated file, then add a tag to the Service component (with keypath='yes') above ServiceInstall.

Below is my final .wxs and .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>
like image 145
aweyeahdawg Avatar answered Sep 23 '22 12:09

aweyeahdawg