// ServiceBaseExtensions.cs using System; using System.Collections.Generic; using System.Reflection; using System.ServiceProcess; namespace MyNamespace { public static class ServiceBaseExtensions { /// /// Runs a given collection of services and hosts them in either /// Console Application or Windows Service depending on /// how the application is executed (in interactive mode or not). /// /// The output type of the application must be set to Console: /// Project properties -> Output type: Console Application. /// /// Array of services to run. /// Arguments to be passed to the services. public static void Run(this ServiceBase[] servicesToRun, string[] args) { if (!Environment.UserInteractive) { ServiceBase.Run(servicesToRun); return; } Console.WriteLine("Running services in interactive mode..."); Console.WriteLine(); CallServiceBaseMethod(servicesToRun, "OnStart", new object[] { args }, "Starting"); Console.WriteLine("Press any key to stop the services..."); Console.ReadKey(); CallServiceBaseMethod(servicesToRun, "OnStop", null, "Stopping"); Console.WriteLine(); Console.WriteLine("Press any key to exit... "); Console.ReadKey(); } private static void CallServiceBaseMethod(IEnumerable services, string methodName, object[] methodArgs, string consoleMessage) { MethodInfo onStopMethod = typeof(ServiceBase).GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic); foreach (ServiceBase service in services) { Console.Write("{0} '{1}' ... ", consoleMessage, service.ServiceName); onStopMethod.Invoke(service, methodArgs); Console.Write("OK"); } Console.WriteLine(); } } } // Program.cs /* SAMPLE USAGE: */ namespace MyNamespace { static class Program { static void Main(string[] args) { System.ServiceProcess.ServiceBase[] services = new System.ServiceProcess.ServiceBase[] { new MyWindowsService() }; services.Run(args); } } }