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:
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:
Short on time, just some links to see if it gets you going:
Essentially:
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:
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.
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>