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