Click here to Skip to main content
Click here to Skip to main content

HybridService: Easily Switch Between Console Application and Service

By , 26 Jun 2007
Rate this:
Please Sign up or sign in to vote.

Screenshot - hybridservice.jpg

Introduction

Recently, I ran into a problem while developing a client/server application. I needed to turn the server (console application) into a service so that it would run when the server started, without having to log into the machine. In the past, I would have left the console application as-is, started another project as the actual service and have it launch the console application. Then I would to start yet another project to do the actual installing and uninstalling of the service. Many of you might have used a similar technique and I'm sure you can all agree that having three executable files for switching between console and service is a real pain. So, I went scouring the internet and found an excellent article by Chris Mullins which put me in the right direction.

Using the code

If you have already created the console application, you will need to move it from the Program.cs file to the ConsoleApplication.cs class provided in the demo application. This may take some work if you built your entire application in the Program.cs file. If you haven't built your application yet, you're in luck as it's very simple to use this code. I would recommend using the demo project as your new project, as everything you need is already there. All you need to do is build your application in ConsoleApplication.cs, using the constructor as you would use the entry point of Program.cs. Here is a quick example of using the ConsoleApplication.cs file:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace HybridService
{
    class ConsoleApplication
    {
        public ConsoleApplication(string applicationPath, bool consoleMode)
        {
            //This is where your console application would be

            Console.WriteLine("Hybrid Service Application");
            Console.WriteLine();

            StreamWriter stream = 
                new StreamWriter(applicationPath + "\\output.txt", true);
            stream.WriteLine(DateTime.Now.ToString("f") + "   It works! \n");
            stream.Flush();
            stream.Close();
            stream.Dispose();

            Console.WriteLine(
                "I have written to " + applicationPath + "\\output.txt");
            Console.WriteLine("Press any key to exit...");
            if (consoleMode) Console.ReadKey();

            //If you need to exit the application before 
            //it reaches this point, you need to use the line below, or 
            //the service will not stop running.
            //But if you are running a socket server or something that 
            //needs to stay alive after this method has been executed, 
            //remove the line below.
            Environment.Exit(0);
        }

        public void Close()
        {
            //Application is exiting. This is where your cleanup code 
            //should be. For example, a socket server would need 
            //"mySocketListener.Close();"
        }
    }
}

You will also need to open the Program.cs file and give your application a name that will be displayed in the Services window.

applicationTitle = "My Hybrid Service";

Running the application

If you were to start debugging this application right now, it would show up as a console window. This is great for testing and debugging, but when you're ready to move it into production as a service, you would normally need to jump through hoops. Then if you needed to debug something, you would have to jump through those hoops all over again, but not anymore! Now it is easier than ever to switch between console and service. You don't even have to change your code. All you need to do is build your project, open a Command Window, navigate to your project's Release folder, and use the following command line argument:

HybridService -service

Your program will now install the service and run it once it's installed. It has also been configured to start when your machine boots. If you need to make changes to the program, stop the service and rebuild your application. That's it. Once you're done testing it in production, you will need to uninstall the service so that it doesn't linger on your machine. Use this command line argument:

HybridService -noservice

Your service has now been stopped (if it was running) and uninstalled.

Points of interest

I personally think this is the greatest thing since sliced bread, but I'm biased. However, there are some things that you need to be aware of:

  • You cannot have spaces in your executable's name, and its extension must be .exe
  • Since you aren't running your code in a static class, you cannot use "return" or Application.Exit(). You have to use Environment.Exit(0) to end your application.
  • Avoid using Console.Read() or any other blocking calls requiring user-input. If you need to use it only in console mode, check for the consoleMode argument. The above example demonstrates this.
  • Don't use Environment.CurrentDirectory unless you want it to return the System32 folder. Use the applicationPath argument instead. Again, this is demonstrated above.
  • Before renaming or moving your executable, make sure it is NOT installed as a service!
  • You cannot install your application as a service if the executable is not on your local machine. Trying to install the service from a network drive will NOT work.
  • Another little annoying Windows'ism is that you MUST close the Services window when you uninstall the service or it will stay in the list of services until you close it. Refreshing the window will NOT work. You have to close and re-open it.

Final notes

I would, again, like to thank Chris Mullins for posting his code. As for the ServiceInstaller, it is a modified version of some code I found about a year ago. I can't remember who the original author was, but if you know, send me a link to the original code and I'll post a thank-you to him/her as well. I hope this code helps someone. It has helped me quite a bit. Also, I would appreciate some feedback. This is my first post to CodeProject, so I'm interested in learning how I did. If you find any problems, let me know. If you use this in your project, I only ask that you give me credit for it in your application.

History

  • 2007-06-22: Article posted

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Ross Peoples
Web Developer
United States United States
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 PinmemberChris_Inman14-Jun-12 7:32 
GeneralGetting error: 'System.ServiceProcess.ServiceInstaller' does not contain a definition for 'UnInstallService' Pinmembergloby10-Sep-09 16:40 
GeneralCode Pinmemberdm328110-Dec-08 16:53 
GeneralNice, but there is a better solution. PinmemberAlexander Stuckenholz29-Jun-08 22:30 
GeneralRe: Nice, but there is a better solution. Pinmemberluisperezphd1-May-11 5:40 
GeneralWorks Great! PinmemberNorbert1712-Jun-08 6:24 
GeneralGreat article !!! PinmemberHans-Jürgen Schmidt28-Jan-08 0:49 
GeneralTo anyone having a problem with service stuck at starting PinmemberRoss Peoples24-Jul-07 2:23 
NewsFixed! (Now it Starts) Pinmembertravislaborde11-Jul-07 7:40 
GeneralRe: Fixed! (Now it Starts) PinmemberStewart Roberts11-Jul-07 10:06 
GeneralRe: Fixed! (Now it Starts) Pinmembertravislaborde12-Jul-07 4:56 
QuestionRe: Fixed! (Now it Starts) PinmemberStewart Roberts12-Jul-07 8:22 
AnswerRe: Fixed! (Now it Starts) Pinmembertravislaborde16-Jul-07 2:10 
GeneralService stays in "Starting" mode until the Constructor code completes PinmemberJamesMMM10-Jul-07 10:44 
GeneralRe: Service stays in "Starting" mode until the Constructor code completes Pinmembertravislaborde11-Jul-07 7:40 
Questionnice, but.... Pinmembertravislaborde10-Jul-07 9:08 
AnswerRe: nice, but.... Pinmembertravislaborde11-Jul-07 7:09 
GeneralService won't start PinmemberStewart Roberts4-Jul-07 4:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140421.2 | Last Updated 26 Jun 2007
Article Copyright 2007 by Ross Peoples
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid