Run a Windows Service as a console app
Before a Windows Service can run, it has to be "installed" first using installutil. EG:
C:\installutil -i c:\path\to\project\debug\service.exe
Then you can open up the list of Services to start it. EG:
- Right click 'My Computer'
- Click on 'Manage'
- Open up 'Services and Applications'
- Click on 'Services'
- Find your service in the list and right-click on it
- Click on 'Start'
Once it has started, you can go into Visual Studio, click on 'Debug', then click on 'Attach to Process'.
Another technique is to add this line to your OnStart() method in the service:
System.Diagnostics.Debugger.Launch();
When you do that, it'll prompt you to pick an instance of Visual Studio to debug the service in.
You can alter the assembly's startup mode based on whether you're in DEBUG mode (usually inside Visual Studio but not necessarily) or RELEASE mode (when it runs as a service in production):
Change this:
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
}
}
to that:
static class Program
{
static void Main()
{
#if(!DEBUG)
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
#else
MyService myServ = new MyService();
myServ.Process();
// here Process is my Service function
// that will run when my service onstart is call
// you need to call your own method or function name here instead of Process();
#endif
}
}
The technique is taken from this article and the credit is for the article's author, Tejas Vaishnav. I copied the code fragments here because SO favors full answers rather than links that might disappear some time.
To prevent this error occurring and allow the service to run outside of the usual service controller you can check the Environment.UserInteractive
flag. If it is set you can run the service with output to the console instead of letting it run to the ServiceBase code that returns that error.
Add this to the start of Program.Main(), before the code that uses ServiceBase to run the service:
if (Environment.UserInteractive)
{
var service = new WindowsService();
service.TestInConsole(args);
return;
}
As the OnStart and OnStop methods are protected
in your service you need to add another method to that class which you can run from Main() and calls those methods for you, such as:
public void TestInConsole(string[] args)
{
Console.WriteLine($"Service starting...");
this.OnStart(args);
Console.WriteLine($"Service started. Press any key to stop.");
Console.ReadKey();
Console.WriteLine($"Service stopping...");
this.OnStop();
Console.WriteLine($"Service stopped. Closing in 5 seconds.");
System.Threading.Thread.Sleep(5000);
}
Finally, make sure the output is a console application in the project's properties.
You can now run the service executable like any other and it will start as a console. If you start it from Visual Studio the debugger will attach automatically. If you register it and start it as a service it will run properly as a service without any changes.
The only difference I've found is that when running as a console application the code does not write to the event log, you might want to output anything you would normally log there to the console as well.
This service debugging technique is one of those explained on docs.microsoft.com
There is a nuget package made to solve this problem: install-package WindowsService.Gui
What does the package do?
It helps by creating a Play/Stop/Pause UI when running with a debugger attached, but also allows the windows service to be installed and run by the Windows Services environment as well. All this with one line of code! What is Service Helper Being someone who writes Windows Services a lot, it can be frustrating to deal with the headaches involved in debugging services. Often it involves tricks, hacks, and partial workarounds to test all of your code. There is no "just hit F5" experience for Windows Services developers.
Service Helper solves this by triggering a UI to be shown if a debugger is attached that simulates (as closely as possible) the Windows Services Environment.
The github project is here: https://github.com/wolfen351/windows-service-gui
How to use?
The easiest way to get Windows Service Helper in your project is to use the NuGet package ServiceProcess.Helpers on the NuGet official feed.
Simply make a few changes to the typical code in the "Program.cs" for your application:
using System.ServiceProcess;
using ServiceProcess.Helpers; //HERE
namespace DemoService
{
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
//ServiceBase.Run(ServicesToRun);
ServicesToRun.LoadServices(); //AND HERE
}
}
}
Disclosure: I'm the maintainer of this project
Note: The UI is optional
Another reason can be that the solution configuration is in Release mode in place of Debug mode