#if !NETSTANDARD1_3 namespace Unosquare.Swan { using System; using System.Collections.Generic; using System.Reflection; using System.Threading; #if NET452 using System.ServiceProcess; #else using Abstractions; #endif /// /// Extension methods. /// public static class WindowsServicesExtensions { /// /// Runs a service in console mode. /// /// The service to run. public static void RunInConsoleMode(this ServiceBase serviceToRun) { if (serviceToRun == null) throw new ArgumentNullException(nameof(serviceToRun)); RunInConsoleMode(new[] { serviceToRun }); } /// /// Runs a set of services in console mode. /// /// The services to run. public static void RunInConsoleMode(this ServiceBase[] servicesToRun) { if (servicesToRun == null) throw new ArgumentNullException(nameof(servicesToRun)); const string onStartMethodName = "OnStart"; const string onStopMethodName = "OnStop"; var onStartMethod = typeof(ServiceBase).GetMethod(onStartMethodName, BindingFlags.Instance | BindingFlags.NonPublic); var onStopMethod = typeof(ServiceBase).GetMethod(onStopMethodName, BindingFlags.Instance | BindingFlags.NonPublic); var serviceThreads = new List(); "Starting services . . .".Info(Runtime.EntryAssemblyName.Name); foreach (var service in servicesToRun) { var thread = new Thread(() => { onStartMethod.Invoke(service, new object[] { new string[] { } }); $"Started service '{service.GetType().Name}'".Info(service.GetType()); }); serviceThreads.Add(thread); thread.Start(); } "Press any key to stop all services.".Info(Runtime.EntryAssemblyName.Name); Terminal.ReadKey(true, true); "Stopping services . . .".Info(Runtime.EntryAssemblyName.Name); foreach (var service in servicesToRun) { onStopMethod.Invoke(service, null); $"Stopped service '{service.GetType().Name}'".Info(service.GetType()); } foreach (var thread in serviceThreads) thread.Join(); "Stopped all services.".Info(Runtime.EntryAssemblyName.Name); } } } #endif