{"id":91176,"date":"2019-03-29T18:39:51","date_gmt":"2019-03-29T18:39:51","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/aspnet\/?p=21689"},"modified":"2019-03-29T18:39:51","modified_gmt":"2019-03-29T18:39:51","slug":"net-core-workers-as-windows-services","status":"publish","type":"post","link":"https:\/\/sickgaming.net\/blog\/2019\/03\/29\/net-core-workers-as-windows-services\/","title":{"rendered":".NET Core Workers as Windows Services"},"content":{"rendered":"<div class=\"row justify-content-center\">\n<div class=\"col-md-2\">\n<div><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/net-core-workers-as-windows-services.jpg\" width=\"58\" height=\"58\" alt=\"Avatar\" class=\"avatar avatar-58 wp-user-avatar wp-user-avatar-58 photo avatar-default\"><\/p>\n<p>Glenn<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"entry-meta\">\n<p>March 29th, 2019<\/p>\n<p> &lt;!&#8211;<span class=\"posted-on\">Posted on <a href=\"https:\/\/devblogs.microsoft.com\/aspnet\/net-core-workers-as-windows-services\/\" rel=\"bookmark\"><time class=\"entry-date published\" datetime=\"2019-03-29T11:39:51+00:00\">March 29, 2019<\/time><time class=\"updated\" datetime=\"2019-03-29T11:47:44+00:00\"> (March 29, 2019) <\/time><\/a><\/span><span class=\"byline\"> by <span class=\"author vcard\"><a class=\"url fn n\" href=\"https:\/\/devblogs.microsoft.com\/aspnet\/author\/glenncmicrosoft-com\/\">Glenn Condron [MSFT]<\/a><\/span><\/span>&#8211;&gt; <\/div>\n<p><!-- .entry-meta --> <\/p>\n<p>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.<\/p>\n<h2>Create a worker<\/h2>\n<p><strong><em>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 Server template directly inside the create new project wizard.<\/em><\/strong><\/p>\n<h3>Create a Worker in Visual Studio<\/h3>\n<p><img decoding=\"async\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/net-core-workers-as-windows-services.png\" alt=\"image\"><\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/net-core-workers-as-windows-services-1.png\" alt=\"image\"><\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/net-core-workers-as-windows-services-2.png\" alt=\"image\"><\/p>\n<h3>Create a Worker on the command line<\/h3>\n<p>Run <code>dotnet new worker<\/code><\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/net-core-workers-as-windows-services-3.png\" alt=\"image\"><\/p>\n<h2>Run as a Windows Service<\/h2>\n<p>In order to run as a Windows Service we need our worker to listen for start and stop signals from <code>ServiceBase<\/code> the .NET type that exposes the Windows Service systems to .NET applications. To do this we want to:<\/p>\n<p>Add the <code>Microsoft.Extensions.Hosting.WindowsServices<\/code> NuGet package<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/net-core-workers-as-windows-services-4.png\" alt=\"image\"><\/p>\n<p>Add the <code>UseServiceBaseLifetime<\/code> call to the <code>HostBuilder<\/code> in our Program.cs<\/p>\n<pre><code class=\"csharp\">public class Program\n{ public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) =&gt; Host.CreateDefaultBuilder(args) .UseServiceBaseLifetime() .ConfigureServices(services =&gt; { services.AddHostedService&lt;Worker&gt;(); });\n}\n<\/code><\/pre>\n<p>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\u2019t then it noops which makes this method safe to be called when running locally or when running as a Windows Service. You don\u2019t need to add guard clauses to it and can just run the app normally when not installed as a Windows Service.<\/p>\n<p>Secondly, it configures your host to use a <code>ServiceBaseLifetime<\/code>. <code>ServiceBaseLifetime<\/code> works with <code>ServiceBase<\/code> to help control the lifetime of your app when run as a Windows Service. This overrides the default <code>ConsoleLifetime<\/code> that handles signals like CTL+C.<\/p>\n<h3>Install the Worker<\/h3>\n<p>Once we have our worker using the <code>ServiceBaseLifetime<\/code> we then need to install it:<\/p>\n<p>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.<\/p>\n<pre><code>dotnet publish -o c:\\code\\workerpub\n<\/code><\/pre>\n<p>Then we can use the <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/desktop\/services\/controlling-a-service-using-sc\">sc utility<\/a> in an admin command prompt<\/p>\n<pre><code>sc create workertest binPath=c:\\code\\workerpub\\WorkerTest.exe\n<\/code><\/pre>\n<p>For example:<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/net-core-workers-as-windows-services-5.png\" alt=\"image\"><\/p>\n<p><em><strong>Security note:<\/strong> This command has the service run as local system, which <strong>isn\u2019t something you will generally want to do<\/strong>. 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: <a href=\"https:\/\/docs.microsoft.com\/en-us\/aspnet\/core\/host-and-deploy\/windows-service?view=aspnetcore-2.2\">https:\/\/docs.microsoft.com\/en-us\/aspnet\/core\/host-and-deploy\/windows-service?view=aspnetcore-2.2<\/a><\/em><\/p>\n<h2>Logging<\/h2>\n<p>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 <code>Microsoft.Extensions.Logging.EventLog<\/code> package and then modify your <code>Program.cs<\/code>:<\/p>\n<pre><code class=\"csharp\">public static IHostBuilder CreateHostBuilder(string[] args) =&gt; Host.CreateDefaultBuilder(args) .ConfigureLogging(loggerFactory =&gt; loggerFactory.AddEventLog()) .ConfigureServices(services =&gt; { services.AddHostedService&lt;Worker&gt;(); });\n<\/code><\/pre>\n<p>In upcoming previews we plan to improve the experience of using Workers with Windows Services by:<\/p>\n<ol>\n<li>Rename UseWindowsServiceBaseLifetime to UseWindowsService<\/li>\n<li>Add automatic and improved integration with the Event Log when running as a Windows Service.<\/li>\n<\/ol>\n<p>We hope you try out this new template and want you to let us know how it goes, you can file any bugs or suggestions here: <a href=\"https:\/\/github.com\/aspnet\/AspNetCore\/issues\/new\/choose\">https:\/\/github.com\/aspnet\/AspNetCore\/issues\/new\/choose<\/a><\/p>\n<div class=\"authorinfoarea\">\n<div><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.sickgaming.net\/blog\/wp-content\/uploads\/2019\/03\/net-core-workers-as-windows-services-1.jpg\" width=\"96\" height=\"96\" alt=\"Avatar\" class=\"avatar avatar-96 wp-user-avatar wp-user-avatar-96 photo avatar-default\"><\/div>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Glenn March 29th, 2019 &lt;!&#8211;Posted on March 29, 2019 (March 29, 2019) by Glenn Condron [MSFT]&#8211;&gt; 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 [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":91177,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[66],"tags":[498,67],"class_list":["post-91176","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-webdev","tag-net-core","tag-aspnetcore"],"_links":{"self":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/91176","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/comments?post=91176"}],"version-history":[{"count":0,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/posts\/91176\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media\/91177"}],"wp:attachment":[{"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/media?parent=91176"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/categories?post=91176"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sickgaming.net\/blog\/wp-json\/wp\/v2\/tags?post=91176"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}