namespace Swan { using Logging; using System; using System.Collections.Generic; using System.Reflection; using System.Threading; #if NET461 using System.ServiceProcess; #else using Services; #endif /// /// Extension methods. /// public static class WindowsServicesExtensions { /// /// Runs a service in console mode. /// /// The service to run. /// The logger source. /// this. [Obsolete("This extension method will be removed in version 3.0")] public static void RunInConsoleMode(this ServiceBase @this, string loggerSource = null) { if (@this == null) throw new ArgumentNullException(nameof(@this)); RunInConsoleMode(new[] { @this }, loggerSource); } /// /// Runs a set of services in console mode. /// /// The services to run. /// The logger source. /// this. /// The ServiceBase class isn't available. [Obsolete("This extension method will be removed in version 3.0")] public static void RunInConsoleMode(this ServiceBase[] @this, string loggerSource = null) { if (@this == null) throw new ArgumentNullException(nameof(@this)); 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); if (onStartMethod == null || onStopMethod == null) throw new InvalidOperationException("The ServiceBase class isn't available."); var serviceThreads = new List(); "Starting services . . .".Info(loggerSource ?? SwanRuntime.EntryAssemblyName.Name); foreach (var service in @this) { var thread = new Thread(() => { onStartMethod.Invoke(service, new object[] { Array.Empty() }); $"Started service '{service.GetType().Name}'".Info(loggerSource ?? service.GetType().Name); }); serviceThreads.Add(thread); thread.Start(); } "Press any key to stop all services.".Info(loggerSource ?? SwanRuntime.EntryAssemblyName.Name); Terminal.ReadKey(true, true); "Stopping services . . .".Info(SwanRuntime.EntryAssemblyName.Name); foreach (var service in @this) { onStopMethod.Invoke(service, null); $"Stopped service '{service.GetType().Name}'".Info(loggerSource ?? service.GetType().Name); } foreach (var thread in serviceThreads) thread.Join(); "Stopped all services.".Info(loggerSource ?? SwanRuntime.EntryAssemblyName.Name); } } }