8

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.

aweyeahdawg
  • 886
  • 9
  • 19
  • 1
    Here are a few links for now: [Debugging Ideas-List](https://stackoverflow.com/questions/53512998/desktop-applicaton-not-opening-after-installation-in-client-system/53530377#53530377), [Dependency Scanning](https://stackoverflow.com/a/51940598/129130), [**Service Debugging**](https://stackoverflow.com/a/55087943/129130). – Stein Åsmul Sep 24 '19 at 20:23
  • Thanks Stein, I've found that if I use framework dependent it works on my machine (since i have .net core installed obviously) but when I switch to self-contained it fails again (even on my machine). – aweyeahdawg Sep 24 '19 at 21:36
  • I've never written a .net core windows service so it's going to come down to this: Does .NET Core actually create a Windows Service like in .NET's ServiceBase that can respond to ServiceStart ServiceStop events or is it basically just a console application running as a worker? If the answer is the later you'll need to use something like SrvAny or NSSM to be a hosting layer. – Christopher Painter Sep 24 '19 at 22:41
  • Yes Chris, I thought as much too. No time to look right now, but here are some links for reference: [`Host ASP.NET Core in a Windows Service`](https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service), [`.NET Core application deployment`](https://learn.microsoft.com/en-us/dotnet/core/deploying/). – Stein Åsmul Sep 24 '19 at 23:28
  • Whoops, posted wrong link. [This](https://github.com/aspnet/Extensions/blob/master/src/Hosting/WindowsServices/src/WindowsServiceLifetime.cs) is the correct one – aweyeahdawg Sep 25 '19 at 01:06
  • 1
    Are you willing to try an open source project I have for this? Follow the "windows service" tutorial except use .net core instead of .net framework to create your service and see if it all works. Based on the link in your last comment I expect it should. https://github.com/iswix-llc/iswix-tutorials – Christopher Painter Sep 25 '19 at 03:03
  • @ChristopherPainter Showing following "Windows could not start the MYSERVICE on local computer. Error 1053 :the service did not respond to the start or control request in a timely fashion" while trying to start the service installed using https://github.com/iswix-llc/iswix-tutorials for worker service as window service. – David Jul 20 '20 at 16:45
  • @David you should ask a new question. In general this indicates a problem with your code or a missing dependency. I usually leave the installer paused at that spot and try to debug the service to see why it's not responding. – Christopher Painter Jul 20 '20 at 23:54

1 Answers1

5

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>
aweyeahdawg
  • 886
  • 9
  • 19