What is the accepted pattern for an application that can be run as a service or as a console application

c#, wcf, windows-services

Solution

I suspect your test project was configured as a windows exe, not a console exe. With a windows exe `Console.ReadLine` will return immediately.

To have a console exe that works both as a service and at the command line, start it as a service project (in Visual Studio) - and add a check on `Environment.UserInteractive` - i.e.

static void Main() {
    if(Environment.UserInteractive) {
        // code that starts the listener and waits on ReadLine
    } else {
        // run the service code that the VS template injected
    }
}

You can of course also use a command line switch. I have example on microsoft.public.dotnet.languages.csharp that acts as:

- an installer / uninstaller

- a service

- a console-mode app

depending on the switches

Problem

I have a project that is deployed to production as a windows service. However for local development purposes it would be useful to run it as a console application. At the moment I have a class Called `ReportingHost` that provides my core functionality, And a class called ReportingServiceHost that inherits from `ServiceBase` and allows me to run the application as a service. There is also a program class with a main method that calls `ServiceBase.Run` on my ReportingServiceHost. I think I need to write a `ReportingConsoleHost` class that allows me to run the functionality in a console. Then I need to modify my `Main` to react to a command line switch and choose one or the other. These are the two bits I am having trouble with. I have had a look at this and attempted to use that code but my app exits immediately, it doesn't show a console window and it doesn't wait for Enter before closing. Part of the problem is that I dont have a deep understanding of how these things work. a definitive pattern for splitting my functionality, my two different ways of running that functionality, and a main method that chooses one of these ways based on a command line argument is what I am hoping to achieve.

Original source