4

I am creating a ASP.net core 2.0 WEB API project that is required to be deploy as a Windows service on a system using a MSI setup. Is there any way I can do it ?

Things that I have already tried:

  1. I created an MSI using Setup Project but it doesn't load any dependencies.

  2. I tried to create an msi using WIX but it shows error The WiX Toolset v3.11 (or newer) build tools must be installed to build this project I have tried solution which are already answered on this and this.

Stein Åsmul
  • 34,628
  • 23
  • 78
  • 140
Mohit Bora
  • 103
  • 1
  • 9

3 Answers3

2

Short on time, just some links to see if it gets you going:

Essentially:

  1. You need to download and install the WiX toolkit to run WiX.
  2. If you want to work with WiX source files in Visual Studio, you should also get the Visual Studio Extension (in addition to the main WiX download).
  3. Download both from here: http://wixtoolset.org/releases/

I like to add the bin folder in the main WiX installation directory to the Path environment variable to be able to call WiX build tools - candle.exe, light.exe, etc... - from anywhere.

You can compile WiX source files outside Visual Studio as well. In its simplest form:

set SetupName=MySetup

candle.exe %SetupName%.wxs >> %SetupName%.log
light.exe -out %SetupName%.msi %SetupName%.wixobj >> %SetupName%.log

Or, without the line-noise:

candle.exe Setup.wxs
light.exe -out Setup.msi Setup.wixobj

Similar Questions:

Stein Åsmul
  • 34,628
  • 23
  • 78
  • 140
1

I solved this by creating an msi using Wix. I watched this Video and followed its instruction.

  • For creating windows service I used NSSM, I copied nssm.exe as a part of installer. used the following command: nssm install service-name

  • For creating service automatically I used the CustomAction of WiX.

Mohit Bora
  • 103
  • 1
  • 9
1

To create an MSI for .Net core 2… first publish your project like

dotnet publish --configuration Release --runtime win7-x64 --self-contained false --output c:\outputfolder

You can make it part of your .wixproj by adding

 <Target Name="BeforeBuild">
    <PropertyGroup>
      <BasePath>$(SolutionDir)\publish\bin\$(Configuration)\FilesToPackage</BasePath>
    </PropertyGroup>
    <!-- Clean previous build folder -->
    <Exec Command="rd /s /q $(BasePath)" />

    <!-- Publish dotnet core app -->
    <Exec Command="dotnet publish $(MSBuildThisFileDirectory)\..\..\src\yourproject.csproj -r win-x64 --self-contained false --output $(BasePath)" />

    <!-- Get assembly version -->
    <GetAssemblyIdentity AssemblyFiles="$(BasePath)\yourproject.dll">
      <Output TaskParameter="Assemblies" ItemName="AssemblyVersion" />
    </GetAssemblyIdentity>

    <!-- Define some variables we need -->
    <PropertyGroup>
      <DefineConstants>ProductVersion=%(AssemblyVersion.Version);BasePath=$(BasePath)</DefineConstants>
    </PropertyGroup>

    <HeatDirectory 
      OutputFile="YourServiceComponent.wxs" 
      DirectoryRefId="INSTALLFOLDER" 
      ComponentGroupName="yourproject_component"
      SuppressCom="true" Directory="$(BasePath)"
      SuppressFragments="true"
      SuppressRegistry="true"
      SuppressRootDirectory="true"
      AutoGenerateGuids="false"
      GenerateGuidsNow="true"
      ToolPath="$(WixToolPath)"
      PreprocessorVariable="var.BasePath"
      Transforms="RemoveFiles.xslt" 
      />
  </Target>

Heat will create the wxs file with all the files from the output but you need to remove yourservice.exe so add that information to RemoveFiles.xslt

<?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">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:key name="pdb-search" match="wix:Component[contains(wix:File/@Source, '.pdb')]" use="@Id" />
  <xsl:template match="wix:Component[key('pdb-search', @Id)]" />
  <xsl:template match="wix:ComponentRef[key('pdb-search', @Id)]" />

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

Finally you want Wix to register your service with Windows Service Control Manager (SCM) so add the following to your Product.wxs

  <Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
      <ComponentGroupRef Id="yourproject_component" />

      <Component Id="ServiceAssemblyComponent" Guid="{GUID}">
        <File Id="ServiceAssembly" Source="$(var.BasePath)\Your.Service.exe" KeyPath="yes" />
        <ServiceInstall Id="ServiceInstallation" DisplayName="$(var.ProductName)" Name="$(var.ProductName)" ErrorControl="normal" Start="auto" Type="ownProcess"  Vital="yes" />
        <ServiceControl Id="ServiceControl" Name="$(var.ProductName)" Stop="both" Remove="uninstall" />
      </Component>
    </ComponentGroup>
  </Fragment>
Xavier John
  • 5,857
  • 3
  • 25
  • 32