.Net Console Application as Windows Service

.NET console application as Windows service

I usually use the following techinque to run the same app as a console application or as a service:

using System.ServiceProcess

public static class Program
{
#region Nested classes to support running as service
public const string ServiceName = "MyService";

public class Service : ServiceBase
{
public Service()
{
ServiceName = Program.ServiceName;
}

protected override void OnStart(string[] args)
{
Program.Start(args);
}

protected override void OnStop()
{
Program.Stop();
}
}
#endregion

static void Main(string[] args)
{
if (!Environment.UserInteractive)
// running as service
using (var service = new Service())
ServiceBase.Run(service);
else
{
// running as console app
Start(args);

Console.WriteLine("Press any key to stop...");
Console.ReadKey(true);

Stop();
}
}

private static void Start(string[] args)
{
// onstart code here
}

private static void Stop()
{
// onstop code here
}
}

Environment.UserInteractive is normally true for console app and false for a service. Techically, it is possible to run a service in user-interactive mode, so you could check a command-line switch instead.

C# Running console application as windows service - The service didn't respond error

I tried your exact steps and it worked for me. I will highlight a few key points that I came across

  1. OnStart should definitely return in a timely fashion. i.e. the work should happen in a separate process/thread. I used your code for thread and it worked fine for me.
  2. Make sure the executable is on a local drive which can be accessed from your "Local System" account without any permission issues.
  3. Make sure when you create the service, you provide the absolute path and not relative path.
  4. Make sure the sc create ... command responds back with [SC] CreateService SUCCESS
  5. Check the service was created in the service control panel
  6. Make sure you can start it from the service control panel before attempting it from command line
  7. Also, open task manager or process explorer to make sure the service executable is running or not (irrespective of what status is returned by service control panel or scm start)
  8. For debugging, I logged the information into a local temp file - again watch out for permissions issues with Local System account.
  9. If for whatever reasons you have to delete the service, make sure that it indeed disappeared from the service control panel

.NET Core 3.1 Console App as a Windows Service

I forgot about answering this question as I solved it a few hours later after I asked it, but you can just add ".UseWindowsService()" to the Host.CreateDefaultBuilder(args) line.
eg:

 public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService() //<==== THIS LINE
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
})
.UseNLog();

Running a C# console application as a Windows service

You cannot just take any console application and run as Windows service. First you need to implement your service class that would inherit from ServiceBase, then in entry point (Main) you need to run the service with ServiceBase.Run(new YourService()). In your service class you need to define what happens when service starts and ends.

Ideally you should add ServiceInstaller to your assembly too. This way you will be able to preset your service properties, and use installutil.exe to install the service.

Run the Console Application as service

Use File->New Project->Visual C#->Windows->Windows Service,

And Add your main code to OnStart(), and OnStop() event handlers, then install it as a service:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;

namespace MyWindowsService
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}

protected override void OnStart(string[] args)
{
}

protected override void OnStop()
{
}
}
}

Host .NET Core console application like Windows Service

In .NET Core 2.1 you can use the Generic Host class to create and run service/daemon like applications.

You can configure and run your application in almost the same way as if it were an ASP.NET Core application. Despite the article titles, this isn't specific to ASP.NET Core, the Generic Host Builder is deployed through the Microsoft.Extensions.Hosting package that has no ASP.NET Core dependency.

The main method could look like this :

public static async Task Main(string[] args)
{
var host = new HostBuilder()
.UseConsoleLifetime()
.ConfigureServices((hostContext, services) =>
{
services.AddLogging();
services.AddHostedService<LifetimeEventsHostedService>();
services.AddHostedService<TimedHostedService>();
})
.Build();

await host.RunAsync();
}

The services that need to run as long as the application runs should implement IHostedService. This is described in Background tasks with hosted services.

The UseConsoleLifetime() call configures the host to check for Ctrl+C and terminate the application. When that happens, the host will call the StopAsync method of any configured service that implements the IHostedService interface.

When RunAsync() is called it will call the StartAsync method of any service that implements IHostedService.

You can also call RunConsoleAsync() to configure console lifetime and start the services without the extra call to UseConsoleLifetime().

RunAsync and RunConsoleAsync will block until the host terminates. You can use Start or StartAsync to start the services and keep processing eg console input or external commands. When the time comes to terminate the application, for example in response to an exit input, you can call StopAsync.

For example :

host.Start();

Console.WriteLine("Type exit or Ctrl+C to exit");
while(Console.ReadLine() !="exit")
{
//..
}

await host.StopAsync();

Of course, this could be used for something more substantial like listening from commands on a port

Making a windows service from a console application

I found the solution for that. In fact, it was just a connection problem and all I had to do was to add permissions to the service in order to let it access the database. Thank you everyone.



Related Topics



Leave a reply



Submit