- .NET Core Workers as Windows Services
- Create a worker
- Create a Worker in Visual Studio
- Create a Worker on the command line
- Run as a Windows Service
- Install the Worker
- Logging
- Future Work
- Create Windows service from executable
- 10 Answers 10
- Running as Windows service #1386
- Comments
- nicolasr75 commented Apr 13, 2016
- davidfowl commented Apr 13, 2016
- nicolasr75 commented Apr 13, 2016
- MaximRouiller commented Apr 13, 2016
- MaximRouiller commented Apr 13, 2016
- nicolasr75 commented Apr 15, 2016
- MaximRouiller commented Apr 15, 2016 •
- MaximRouiller commented Apr 15, 2016
- nicolasr75 commented Apr 15, 2016
- lankaapura commented May 18, 2016
- evkw commented May 19, 2016 •
- pfedotovsky commented May 20, 2016
- ivan-prodanov commented May 26, 2016 •
- Noeek commented Jun 8, 2016
- guardrex commented Jun 25, 2016
- davidfowl commented Jun 25, 2016
- guardrex commented Jun 25, 2016
- lankaapura commented Jun 28, 2016
- gerardo-lijs commented Aug 28, 2016 •
- nicolasr75 commented Aug 28, 2016
- h3smith commented Sep 14, 2016
- douglastimpe commented Sep 14, 2016 •
- gerardo-lijs commented Sep 14, 2016
- h3smith commented Sep 15, 2016 •
.NET Core Workers as Windows Services
In .NET Core 3.0 we are introducing a new type of application template called Worker Service. This template is intended to give you a starting point for writing long running services in .NET Core. In this walkthrough we will create a worker and run it as a Windows Service.
Create a worker
Preview Note: In our preview releases the worker template is in the same menu as the Web templates. This will change in a future release. We intend to place the Worker Service template directly inside the create new project wizard.
Create a Worker in Visual Studio
Create a Worker on the command line
Run dotnet new worker
Run as a Windows Service
In order to run as a Windows Service we need our worker to listen for start and stop signals from ServiceBase the .NET type that exposes the Windows Service systems to .NET applications. To do this we want to:
Add the Microsoft.Extensions.Hosting.WindowsServices NuGet package
Add the UseServiceBaseLifetime call to the HostBuilder in our Program.cs
This method does a couple of things. First, it checks whether or not the application is actually running as a Windows Service, if it isn’t then it noops which makes this method safe to be called when running locally or when running as a Windows Service. You don’t need to add guard clauses to it and can just run the app normally when not installed as a Windows Service.
Secondly, it configures your host to use a ServiceBaseLifetime . ServiceBaseLifetime works with ServiceBase to help control the lifetime of your app when run as a Windows Service. This overrides the default ConsoleLifetime that handles signals like CTL+C.
Install the Worker
Once we have our worker using the ServiceBaseLifetime we then need to install it:
First, lets publish the application. We will install the Windows Service in-place, meaning the exe will be locked whenever the service is running. The publish step is a nice way to make sure all the files I need to run the service are in one place and ready to be installed.
Then we can use the sc utility in an admin command prompt
Security note: This command has the service run as local system, which isn’t something you will generally want to do. Instead you should create a service account and run the windows service as that account. We will not talk about that here, but there is some documentation on the ASP.NET docs talking about it here: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-2.2
Logging
The logging system has an Event Log provider that can send log message directly to the Windows Event Log. To log to the event log you can add the Microsoft.Extensions.Logging.EventLog package and then modify your Program.cs :
Future Work
In upcoming previews we plan to improve the experience of using Workers with Windows Services by:
- Rename UseWindowsServiceBaseLifetime to UseWindowsService
- Add automatic and improved integration with the Event Log when running as a Windows Service.
Create Windows service from executable
Is there any quick way to, given an executable file, create a Windows service that, when started, launches it?
10 Answers 10
To create a Windows Service from an executable, you can use sc.exe :
You must have quotation marks around the actual exe path, and a space after the binPath= .
Note that it will not work for just any executable: the executable must be a Windows Service (i.e. implement ServiceMain). When registering a non-service executable as a service, you’ll get the following error upon trying to start the service:
Error 1053: The service did not respond to the start or control request in a timely fashion.
There are tools that can create a Windows Service from arbitrary, non-service executables, see the other answers for examples of such tools.
Use NSSM( the non-Sucking Service Manager ) to run a .BAT or any .EXE file as a service.
- Step 1: Download NSSM
- Step 2: Install your sevice with nssm.exe install [serviceName]
- Step 3: This will open a GUI which you will use to locate your executable
Extending (Kevin Tong) answer.
Step 1: Download & Unzip nssm-2.24.zip
Step 2: From command line type:
C:\> nssm.exe install [servicename]
it will open GUI as below (the example is UT2003 server), then simply browse it to: yourapplication.exe
Many existing answers include human intervention at install time. This can be an error-prone process. If you have many executables wanted to be installed as services, the last thing you want to do is to do them manually at install time.
Towards the above described scenario, I created serman, a command line tool to install an executable as a service. All you need to write (and only write once) is a simple service configuration file along with your executable. Run
will install the service. stdout and stderr are all logged. For more info, take a look at the project website.
A working configuration file is very simple, as demonstrated below. But it also has many useful features such as and
these extras prove useful.. need to be executed as an administrator
If your service name has any spaces, enclose in «quotes».
I’ve tested a good product for that: AlwaysUp. Not free but they have a 30 days trial period so you can give it a try.
Same as Sergii Pozharov’s answer, but with a PowerShell cmdlet:
See New-Service for more customization.
This will only work for executables that already implement the Windows Services API.
You can check out my small free utility for service create\edit\delete operations. Here is create example:
Go to Service -> Modify -> Create
Executable file (google drive): [Download]
Probably all your answers are better, but — just to be complete on the choice of options — I wanted to remind about old, similar method used for years:
SrvAny (installed by InstSrv)
I created the cross-platform Service Manager software a few years back so that I could start PHP and other scripting languages as system services on Windows, Mac, and Linux OSes:
Service Manager is a set of precompiled binaries that install and manage a system service on the target OS using nearly identical command-line options (source code also available). Each platform does have subtle differences but the core features are mostly normalized.
If the child process dies, Service Manager automatically restarts it.
Processes that are started with Service Manager should periodically watch for two notification files to handle restart and reload requests but they don’t necessarily have to do that. Service Manager will force restart the child process if it doesn’t respond in a timely fashion to controlled restart/reload requests.
Running as Windows service #1386
Comments
nicolasr75 commented Apr 13, 2016
I often would like to create small, zero-configuration/installtion, self-contained, self-hosted web APIs that should run independent of IIS. On the other side they should run 24/7, independent of user logout and automatic system restarts.
What options do I have to run a self-hosted web app as a Windows service instead of a commandline app?
The text was updated successfully, but these errors were encountered:
davidfowl commented Apr 13, 2016
In RC2 there’s a Windows service host https://github.com/aspnet/Hosting/tree/dev/src/Microsoft.AspNetCore.Hosting.WindowsServices. It only works on .NET Framework, not .NET Core (which is probably fine because it’s windows only anyways).
nicolasr75 commented Apr 13, 2016
Thanks David. I think I don’t get how this works. I used the HelloMvc sample from cli-samples and converted it to use net461, restored, built and ran, everything works as expected.
Next I added
«Microsoft.AspNetCore.Hosting.WindowsServices»: «1.0.0-*»
to project.json, restore and build work and
dotnet run
still works.
Now, how to install the service? I thought about doing
sc create MyAspNetService .
But which executable would I use?
There was one created in
bin/Debug/net461
and another one in
bin/Debug/net461/win7-x64
Both of these cannot be started by the SCM.
Or do I have to call dotnet with parameters?
MaximRouiller commented Apr 13, 2016
Something similar found here:
MaximRouiller commented Apr 13, 2016
I think dnx could be easily be replaced by dotnet on the cmd prompt.
nicolasr75 commented Apr 15, 2016
Thanks for the link. I tried to transfer the ideas but in the end couldn’t get it to work. I list the steps I tried:
Added
Microsoft.AspNetCore.Hosting.WindowsServices
to the dependencies.
Derived the Program class from WebHostService.
At this point dotnet restore, dotnet build and dotnet run all work.
Then I did dotnet publish and tried to start the exe in
bin\Debug\net461\win7-x64\publish
directly which also worked.
Then I used sc.exe create . to register this exe as a service but the scm fails to start it with timeout.
According to the article you posted I also tried to call it via
dotnet run mypath
or
dotnet mypath run
but that doesn’t work either because dotnet does not seem to understand a path parameter.
At that point I ran out of ideas 🙁
MaximRouiller commented Apr 15, 2016 •
Is dotnet in your global path?
The actual command should be something like this :
Another example I found was something like this:
MaximRouiller commented Apr 15, 2016
If you can copy/paste what you tried and the output, we could help a bit more.
nicolasr75 commented Apr 15, 2016
Here is what I did.
I modified HelloMvc sligthly, see the following project.json and Program.cs
dotnet restore, dotnet build and dotnet run work.
Then I did dotnet publish to create a self-contained package that I transferred to a test computer. On that test computer dotnet is installed and returns the following information
.NET Command Line Tools (1.0.0-rc2-002395)
Product Information:
Version: 1.0.0-rc2-002395
Commit Sha: c83a2fb6f9
Runtime Environment:
OS Name: Windows
OS Version: 10.0.10586
OS Platform: Windows
RID: win10-x64
Navigated into the publish directory and did
So this works as expected. Now I tried to register this HelloMvc.exe as a service with
Trying to start it fails:
The Windows Event Log shows
A timeout was reached (60000 milliseconds) while waiting for the AspNetTestService service to connect.
Should I really try to increase the timeout and test again? I think I really misunderstand how it’s supposed to work.
I will try your suggestions now.
lankaapura commented May 18, 2016
Does anyone tried this with RC2? Would be great if can share a sample.
evkw commented May 19, 2016 •
Ive got a service running with something that looks like below. Using net451 framework though.
My service takes in a config.json however and because services run from System32, if the config.json file is not there, it fails.
Havent figured out how to make the service look for files in the executables path
pfedotovsky commented May 20, 2016
@evkw Could you please provide full source code?
ivan-prodanov commented May 26, 2016 •
Guys, I just wrote an answer at StackOverflow about this. I got a console app running as a website app hosted as a windows service (sounds cozy I know)
Noeek commented Jun 8, 2016
The important key point is:
host.RunAsService();
not «host.Run();»
guardrex commented Jun 25, 2016
. works on .NET Framework, not .NET Core (which is probably fine because it’s windows only anyways).
. except that Nano Server can’t do that. Will .NET Core get a Windows Service capability (for Nano) eventually?
davidfowl commented Jun 25, 2016
That’s not currently on the roadmap. I’d file an issue on CoreFx asking for ServiceBase to be ported over.
guardrex commented Jun 25, 2016
Ok, thanks. Will do. In the meantime, I’m looking at a GPO startup script to fire up a console app. https://technet.microsoft.com/en-us/library/cc770556(v=ws.11).aspx
lankaapura commented Jun 28, 2016
@pfedotovsky I’ve updated the Music Store application to run as a service and full sample available here.
Thanks @evkw for SO answer.
gerardo-lijs commented Aug 28, 2016 •
@nicolasr75 I was needing exactly the type of project you were asking for and the good news is that it’s really simple now with ASP.NET Core 1.0 using Microsoft.AspNetCore.Hosting.WindowsServices dependency.
I created a bare minimum sample repo to demonstrate it and from there it would be really simple to copy/paste to your current API or MVC project.
nicolasr75 commented Aug 28, 2016
@gerardo-lijs great example. Thanks for that! I especially like the distinction between console, debug and service.
h3smith commented Sep 14, 2016
Is there a path (or what is the path) to build a «service» that is cross platform?
ie: We have an old .NET 4.5 Windows service that performs background tasks (emails, notifications, etc).
We’d want to bring this to .NET Core and run it in Docker — but the question is what is the best approach? Is it along the lines of @gerardo-lijs? But, how are long running tasks defined and managed if we went the Kestrel route?
douglastimpe commented Sep 14, 2016 •
Without knowing a lot about what you’re trying to accomplish, how helpful do you find the following information after you’ve had a chance to try it out?
gerardo-lijs commented Sep 14, 2016
Hi @h3smith, without know the specifics of your service, I would say generally speaking that if you want to run some .NET code that provides some services in Linux, Mac or Windows you have to target the .Net Core Framework and probably the best path will be to provide some sort of Web API using JSON to interact with it. Long running background task is kind of specific to Windows Services. When using Web API, probably you will refactor some of your code to work in a more disconnected kind of way. Probably in your case, it would be better to use nginx to access your API and manage SSL security instead of Kestrel.
h3smith commented Sep 15, 2016 •
Gents, thanks for the input. Use case so far is simple. We have a Windows Service (.NET 4.5) that sits and polls our database every 1-10 seconds (depends on settings) to see if there are emails or push notifications to send out.
We’d like to get this on .NET Core, obviously as soon as we can.
I guess the real question is, (I know we can’t be the only folk with services like that), what is the best guidance? Our end goal is to drop this in Docker and make it incredibly easy to configure and deploy.
So, obviously Windows is seemingly easy — deploy it as a Windows Service, but trying to be platform independent there doesn’t seem to be clear guidance or direction to take.
(But must say, we’ve migrated the rest of our stack to .NET Core and, just amazing job and love it all)