#if !NETSTANDARD1_3 using System; using System.Collections.Generic; using System.Reflection; using System.Threading; #if NET452 using System.ServiceProcess; #else using Abstractions; #endif namespace Unosquare.Swan { /// /// 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"; MethodInfo onStartMethod = typeof(ServiceBase).GetMethod(onStartMethodName, BindingFlags.Instance | BindingFlags.NonPublic); MethodInfo onStopMethod = typeof(ServiceBase).GetMethod(onStopMethodName, BindingFlags.Instance | BindingFlags.NonPublic); List serviceThreads = new List(); "Starting services . . .".Info(Runtime.EntryAssemblyName.Name); foreach(ServiceBase service in servicesToRun) { Thread 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(ServiceBase service in servicesToRun) { _ = onStopMethod.Invoke(service, null); $"Stopped service '{service.GetType().Name}'".Info(service.GetType()); } foreach(Thread thread in serviceThreads) { thread.Join(); } "Stopped all services.".Info(Runtime.EntryAssemblyName.Name); } } } #endif