One of the common problems that we face in designing a Windows service is the ease of debugging it. I have followed a pattern to solve this problem where I can run a service from either command line or as a service.

 

The steps below outline the changes you would need to make to enable this in your service. Also included are code snippets that show the point.

 

1.         Modify your Service.

a.       Add a RunConsole() method that performs a OnStart(), waits for user to quit and a OnStop() call.

b.      Add a RunService() method to Run the process as a normal service.

 

        /// <summary>

        /// Runs the service as a console app.

        /// </summary>

        internal static void RunConsole()

        {

            using (MyService consoleService = new MyService())

            {

                consoleService.OnStart(null);

                // Wait for the user to quit the program.

                Console.WriteLine("Press \'q\' to quit");

                while (Console.Read() != 'q') ;

                consoleService.OnStop();

            }

        }

 

        /// <summary>

        /// Runs normally

        /// </summary>

        internal static void RunService()

        {

            System.ServiceProcess.ServiceBase.Run(new MyService());

     }

2.       Modify your startup program.

a.       Update your Main(string[] args) to accept arguments, and if the first argument is a /c, call  RunConsole() (above), else call RunService().

 

        /// <summary>

        /// The main entry point for the service...

        /// It will run the executable as a service

        /// unless /c is specified in which case it will run as a console app.

        /// </summary>

        static int Main(string[] args)

        {

            int retCode = 0;

 

            if (args.Length > 1)

            {

                PrintUsage();

                retCode = 1;

            }

            else if (args.Length == 1)

            {

                if ((args[0] != null) && (args[0].Length >= 2))

                {

                    switch (args[0][0])

                    {

                        case '-':

                        case '/':

                            switch (args[0][1])

                            {

                                case 'c':

                                case 'C':

                                    MyService.RunConsole();

                                    break;

                                default:

                                    PrintUsage();

                                    retCode = 1;

                                    break;

                            }

                            break;

                        default:

                            PrintUsage();

                            retCode = 1;

                            break;

                    }

                }

                else

                {

                    PrintUsage();

                    retCode = 1;

                }

            }

            else

            {

                MyService.RunService();

            }

 

            return retCode;

        }

 

 That's it.