This repo contains a library for running a .NET Core application as Windows service without the need for a wrapper assembly or the full (desktop) .NET Framework. It is built using P/Invoke calls into native Windows assemblies.
Usage scenarios include:
Prerequisites:
.csproj
based tooling)> cd samples\TestService
> dotnet restore
> dotnet run --register-service --urls http://*:5080
...
Successfully registered and started service "Demo .NET Core Service" ("Demo ASP.NET Core Service running on .NET Core")
Open http://localhost:5080
in a browser. You should see Hello world
.
The "Services" administrative tool should show the service:
> dotnet run --unregister-service
...
Successfully unregistered service "Demo .NET Core Service" ("Demo ASP.NET Core Service running on .NET Core")
The service may show up as disabled
for some time until all tools accessing the Windows services APIs have been closed.
See this Stack Overflow question.
Add a NuGet package reference to DasMulli.Win32.ServiceUtils
.
Write a Windows service using:
using DasMulli.Win32.ServiceUtils;
class Program
{
public static void Main(string[] args)
{
var myService = new MyService();
var serviceHost = new Win32ServiceHost(myService);
serviceHost.Run();
}
}
class MyService : IWin32Service
{
public string ServiceName => "Test Service";
public void Start(string[] startupArguments, ServiceStoppedCallback serviceStoppedCallback)
{
// Start coolness and return
}
public void Stop()
{
// shut it down again
}
}
You can then register your service via sc.exe (run cmd / powershell as administrator!):
sc.exe create MyService DisplayName= "My Service" binpath= "C:\Program Files\dotnet\dotnet.exe C:\path\to\MyService.dll --run-as-service"
Now go to Services or Task Manager and start your service.
sc
will install your service as SYSTEM
user which has way to many access rights to run things like web apps.
See its reference for more options.
If you want to get rid of it again, use:
sc.exe delete MyService
You can also create a service that registers itself like the example provided by taking a look at the sample source.
Also take a look at the ASP.NET Core MVC sample which has additional logic to set the correct working directory.
When running it in development and not from the published output, be sure to pass --preserve-working-directory
to it when registering
so that it will run from the project directory (e.g. run dotnet run --register-service --preserve-working-directory
from and administrative
command prompt).
To create a service that supports being paused and later continued or stopped, implement IPausableWin32Service
which extends IWin32Service
by Pause()
and Continue()
methods
you can use to implement your pause & continue logic.
Win32Exception
if something goes wrong (Its message should be
interpretable on Windows).IWin32ServiceStateMachine
to implement custom behavior.
Copy SimpleServiceStateMachine
as a starting point to implement extended services.