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);
}
}
}