Gotcha

  1. Imagine you have a dot net core application you initially created as a console application. You can easily run it as a windows service by supplying the well known UseWindowsService() extension method. It took Microsoft a while to supply this, but they eventually did and it works great.
  2. Now imagine you decided all of a sudden, “I like my windows service the way it works now, but something’s missing. It needs a management interface! I know! I will just throw on a web application.” Oh if only…

Sadly, the order of operations matter here and you cannot achieve what I laid out. It’s a foundational change/problem and I don’t even think I can blame Microsoft for this one. I am writing about it because it’s just not obvious and I wasted a good amount of hours trying to figure it out. I was able to put a Frankenstein together to sort of make it work, but even then it was not working properly.

What not to do

The Frankenstein I speak of may give you shudders, so please close your door and ask your children to leave the room. I knew what I was doing was stupid, but I wanted to see if it would work and it did shockingly. As outlined above I have a console application I can host as a windows service. I wanted to also host a web application and I really thought it would be as easy as supplying a magic extension method as it is for hosting in a windows service. Spoiler – no such thing exists and it can be very confusing to understand why when you are focused and in a hurry. So I created a monstrosity:

Don’t do this

What I am showing below is an example of what NOT to do because it ended poorly. I was shocked this even ran.

public static async Task<int> Main(string[] args)
{
	try
	{
		var winSvc = CreateWindowsServiceHost(args); //Returns windows service based host
		var webApp = CreateWebApplicationHost(); //Returns web app based host

		await Task.WhenAll(
			winSvc.RunAsync(),
			webApp.RunAsync());

		return 0;
	}
	catch (Exception ex)
	{
		//Logging

		return 1;
	}
}

This example of shoving a square peg through a round hole is me saying, “Why can’t I host a web application from a console application?”

After a lot of observation, it finally dawned on me. My project was never created with web applications in mind, so the necessary framework bits are missing! I could have continued down this path, but it seemed pointless.

Order matters – what you can do

This is not a fast and hard rule because I am sure if I had more time to waste I could have gotten my ugly example above to completely work, but instead what I did was after realizing that attempting to host a web application from a console application wasn’t going to work I changed gears.

  1. I created a brand new dot net core empty web application
  2. Copied over my console application code accordingly
  3. Bootstrapped the web application to be hosted as a windows service
    1. This is doing double duty because it is also hosting my original windows service (console application) code.

This immediately resolved my woes. This was an important lesson in, “Order of operation matters.” and what I mean by this is:

  • If you never intend to host a web application then using a console application as the base for your windows service is fine.
  • If you intend on providing a web interface, then you must start with a web application as your base as it will already have the necessary frameworks installed at the template level.
    • In other words, a console application is not a web application.
    • Also a web application can be hosted in a windows service as easily as a console application.