using Swan.Logging; using System; using System.Collections.Generic; using System.Reflection; using System.Threading; using Swan.Services; namespace Swan { /// /// 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"; MethodInfo onStartMethod = typeof(ServiceBase).GetMethod(onStartMethodName, BindingFlags.Instance | BindingFlags.NonPublic); MethodInfo onStopMethod = typeof(ServiceBase).GetMethod(onStopMethodName, BindingFlags.Instance | BindingFlags.NonPublic); if(onStartMethod == null || onStopMethod == null) { throw new InvalidOperationException("The ServiceBase class isn't available."); } List serviceThreads = new List(); "Starting services . . .".Info(loggerSource ?? SwanRuntime.EntryAssemblyName.Name); foreach(ServiceBase service in @this) { Thread 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(ServiceBase service in @this) { _ = onStopMethod.Invoke(service, null); $"Stopped service '{service.GetType().Name}'".Info(loggerSource ?? service.GetType().Name); } foreach(Thread thread in serviceThreads) { thread.Join(); } "Stopped all services.".Info(loggerSource ?? SwanRuntime.EntryAssemblyName.Name); } } }