I have found that when developing MicroServices, I often want to run them from within Visual Studio, or just as a console application, and not have to bother with the hassle of installing as windows services.

In the past I have seen this achieved by creating a Class Library project with all the actual implementation inside it, and then both a Console Application and Windows Service project referencing the library and doing nothing other than calling a .Start() method or similar.

While this works, it has always bugged me as there should be a straight forward way of achieving a single exe to do both roles. It turns out there is an easy way to do it too…

Creating the Project

First, create a WindowsService project in VisualStudio: New Windows Service

Then open the project properties, and change the project type to Console Application and set the startup object: Service Type

Next, open Service1.cs and add a new method (and rename it to Service if you feel the need!):

public void StartConsole()
	Console.WriteLine("Press any key to exit...");
	OnStart(new string[] { });


Finally open Program.cs and replace the Main method:

static void Main()
	var service = new Service();

	if (Environment.UserInteractive)
		ServiceBase.Run(new ServiceBase[] { service });

Displaying Output

Calling Console.Write* and Console.Read* methods when running as a windows service will cause exceptions to be thrown, which suggest that you should redirect the console streams to use them under a windows service.

As a MicroService you shouldn’t need to be reading keys from the console (other than the one in our StartConsole method), but writing output would be useful…

To do this I like to use my logging library of choice (Serilog), which I have setup to write to files and to a console:

private void InitializeLogging()
	var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
	var logs = Path.Combine(baseDirectory, "logs");


	Log.Logger = new LoggerConfiguration()
		.WriteTo.RollingFile(Path.Combine(logs, "{Date}.log"))

And call this method inside the Service1 constructor:

public Service()

The Edge Case

There is one slight edge case which I am aware of, which is that the Environment.UserInteractive property can return true even when running as a windows service if when you install the service you tick Allow service to interact with desktop checkbox:


My only solution to this is: Don’t tick that box. I don’t think I have ever used that option anyway!

Wrapping Up

Using this method means less code and projects to maintain, and a very easy path to go from running a service as a desktop application to service.