From a4232549cbbf6857531b55d9900ec21fba9f6c12 Mon Sep 17 00:00:00 2001 From: Qstick Date: Fri, 10 Dec 2021 22:30:12 -0600 Subject: [PATCH] Fix Tray App and Windows Server Restart Co-Authored-By: ta264 --- .../ServiceFactoryFixture.cs | 13 +++-- .../EnvironmentInfo/RuntimeInfo.cs | 11 ++-- src/NzbDrone.Common/Sonarr.Common.csproj | 1 + src/NzbDrone.Console/Sonarr.Console.csproj | 1 - src/NzbDrone.Console/app.config | 14 ----- src/NzbDrone.Console/app.manifest | 31 ---------- src/NzbDrone.Host.Test/ContainerFixture.cs | 9 ++- src/NzbDrone.Host/AppLifetime.cs | 5 +- src/NzbDrone.Host/Bootstrap.cs | 13 ++++- src/NzbDrone.Host/UtilityModeRouter.cs | 3 - src/NzbDrone/Sonarr.csproj | 2 +- src/NzbDrone/SysTray/SysTrayApp.cs | 57 ++++--------------- src/NzbDrone/WindowsApp.cs | 10 ++-- src/NzbDrone/app.config | 14 ----- src/NzbDrone/app.manifest | 31 ---------- 15 files changed, 50 insertions(+), 165 deletions(-) delete mode 100644 src/NzbDrone.Console/app.config delete mode 100644 src/NzbDrone.Console/app.manifest delete mode 100644 src/NzbDrone/app.config delete mode 100644 src/NzbDrone/app.manifest diff --git a/src/NzbDrone.Common.Test/ServiceFactoryFixture.cs b/src/NzbDrone.Common.Test/ServiceFactoryFixture.cs index 51b39189e..f543af256 100644 --- a/src/NzbDrone.Common.Test/ServiceFactoryFixture.cs +++ b/src/NzbDrone.Common.Test/ServiceFactoryFixture.cs @@ -3,6 +3,8 @@ using DryIoc; using DryIoc.Microsoft.DependencyInjection; using FluentAssertions; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Moq; using NUnit.Framework; using NzbDrone.Common.Composition.Extensions; using NzbDrone.Common.EnvironmentInfo; @@ -25,12 +27,15 @@ namespace NzbDrone.Common.Test .AddNzbDroneLogger() .AutoAddServices(Bootstrap.ASSEMBLIES) .AddDummyDatabase() - .AddStartupContext(new StartupContext("first", "second")) - .GetServiceProvider(); + .AddStartupContext(new StartupContext("first", "second")); - container.GetRequiredService().Register(); + container.RegisterInstance(new Mock().Object); - Mocker.SetConstant(container); + var serviceProvider = container.GetServiceProvider(); + + serviceProvider.GetRequiredService().Register(); + + Mocker.SetConstant(serviceProvider); var handlers = Subject.BuildAll>() .Select(c => c.GetType().FullName); diff --git a/src/NzbDrone.Common/EnvironmentInfo/RuntimeInfo.cs b/src/NzbDrone.Common/EnvironmentInfo/RuntimeInfo.cs index c4a22fcc7..4988957e4 100644 --- a/src/NzbDrone.Common/EnvironmentInfo/RuntimeInfo.cs +++ b/src/NzbDrone.Common/EnvironmentInfo/RuntimeInfo.cs @@ -1,9 +1,9 @@ using System; using System.Diagnostics; using System.IO; -using System.Reflection; using System.Security.Principal; -using System.ServiceProcess; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Hosting.WindowsServices; using NLog; using NzbDrone.Common.Processes; @@ -14,14 +14,11 @@ namespace NzbDrone.Common.EnvironmentInfo private readonly Logger _logger; private readonly DateTime _startTime = DateTime.UtcNow; - public RuntimeInfo(IServiceProvider serviceProvider, Logger logger) + public RuntimeInfo(Logger logger, IHostLifetime hostLifetime = null) { _logger = logger; - IsWindowsService = !IsUserInteractive && - OsInfo.IsWindows && - serviceProvider.ServiceExist(ServiceProvider.SERVICE_NAME) && - serviceProvider.GetStatus(ServiceProvider.SERVICE_NAME) == ServiceControllerStatus.StartPending; + IsWindowsService = hostLifetime is WindowsServiceLifetime; // net6.0 will return Sonarr.dll for entry assembly, we need the actual // executable name (Sonarr on linux). On mono this will return the location of diff --git a/src/NzbDrone.Common/Sonarr.Common.csproj b/src/NzbDrone.Common/Sonarr.Common.csproj index 1cc78b3e5..ac5011cac 100644 --- a/src/NzbDrone.Common/Sonarr.Common.csproj +++ b/src/NzbDrone.Common/Sonarr.Common.csproj @@ -6,6 +6,7 @@ + diff --git a/src/NzbDrone.Console/Sonarr.Console.csproj b/src/NzbDrone.Console/Sonarr.Console.csproj index 845fe03cc..aef81527d 100644 --- a/src/NzbDrone.Console/Sonarr.Console.csproj +++ b/src/NzbDrone.Console/Sonarr.Console.csproj @@ -4,7 +4,6 @@ net6.0 ..\NzbDrone.Host\Sonarr.ico - app.manifest Sonarr diff --git a/src/NzbDrone.Console/app.config b/src/NzbDrone.Console/app.config deleted file mode 100644 index 2b0b69660..000000000 --- a/src/NzbDrone.Console/app.config +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/NzbDrone.Console/app.manifest b/src/NzbDrone.Console/app.manifest deleted file mode 100644 index eb0054be9..000000000 --- a/src/NzbDrone.Console/app.manifest +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - - diff --git a/src/NzbDrone.Host.Test/ContainerFixture.cs b/src/NzbDrone.Host.Test/ContainerFixture.cs index 3debf33e6..e7d31dc96 100644 --- a/src/NzbDrone.Host.Test/ContainerFixture.cs +++ b/src/NzbDrone.Host.Test/ContainerFixture.cs @@ -4,6 +4,7 @@ using DryIoc; using DryIoc.Microsoft.DependencyInjection; using FluentAssertions; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Moq; using NUnit.Framework; using NzbDrone.Common; @@ -14,7 +15,6 @@ using NzbDrone.Core.Datastore.Extensions; using NzbDrone.Core.Download; using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.Indexers; -using NzbDrone.Core.Jobs; using NzbDrone.Core.Lifecycle; using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Events; @@ -35,16 +35,15 @@ namespace NzbDrone.App.Test { var args = new StartupContext("first", "second"); - // set up a dummy broadcaster to allow tests to resolve - var mockBroadcaster = new Mock(); - var container = new Container(rules => rules.WithNzbDroneRules()) .AutoAddServices(Bootstrap.ASSEMBLIES) .AddNzbDroneLogger() .AddDummyDatabase() .AddStartupContext(args); - container.RegisterInstance(mockBroadcaster.Object); + // dummy lifetime and broadcaster so tests resolve + container.RegisterInstance(new Mock().Object); + container.RegisterInstance(new Mock().Object); _container = container.GetServiceProvider(); } diff --git a/src/NzbDrone.Host/AppLifetime.cs b/src/NzbDrone.Host/AppLifetime.cs index b9ae84a38..a1c684f95 100644 --- a/src/NzbDrone.Host/AppLifetime.cs +++ b/src/NzbDrone.Host/AppLifetime.cs @@ -20,7 +20,6 @@ namespace NzbDrone.Host private readonly IBrowserService _browserService; private readonly IProcessProvider _processProvider; private readonly IEventAggregator _eventAggregator; - private readonly IUtilityModeRouter _utilityModeRouter; private readonly Logger _logger; public AppLifetime(IHostApplicationLifetime appLifetime, @@ -30,7 +29,6 @@ namespace NzbDrone.Host IBrowserService browserService, IProcessProvider processProvider, IEventAggregator eventAggregator, - IUtilityModeRouter utilityModeRouter, Logger logger) { _appLifetime = appLifetime; @@ -40,7 +38,6 @@ namespace NzbDrone.Host _browserService = browserService; _processProvider = processProvider; _eventAggregator = eventAggregator; - _utilityModeRouter = utilityModeRouter; _logger = logger; appLifetime.ApplicationStarted.Register(OnAppStarted); @@ -72,7 +69,7 @@ namespace NzbDrone.Host private void OnAppStopped() { - if (_runtimeInfo.RestartPending) + if (_runtimeInfo.RestartPending && !_runtimeInfo.IsWindowsService) { var restartArgs = GetRestartArgs(); diff --git a/src/NzbDrone.Host/Bootstrap.cs b/src/NzbDrone.Host/Bootstrap.cs index c32f8085b..2cd9bb2f8 100644 --- a/src/NzbDrone.Host/Bootstrap.cs +++ b/src/NzbDrone.Host/Bootstrap.cs @@ -176,7 +176,18 @@ namespace NzbDrone.Host return ApplicationModes.UninstallService; } - if (OsInfo.IsWindows && WindowsServiceHelpers.IsWindowsService()) + // IsWindowsService can throw sometimes, so wrap it + var isWindowsService = false; + try + { + isWindowsService = WindowsServiceHelpers.IsWindowsService(); + } + catch (Exception e) + { + Logger.Error(e, "Failed to get service status"); + } + + if (OsInfo.IsWindows && isWindowsService) { return ApplicationModes.Service; } diff --git a/src/NzbDrone.Host/UtilityModeRouter.cs b/src/NzbDrone.Host/UtilityModeRouter.cs index 8b94712cd..ae47bb8d0 100644 --- a/src/NzbDrone.Host/UtilityModeRouter.cs +++ b/src/NzbDrone.Host/UtilityModeRouter.cs @@ -16,21 +16,18 @@ namespace NzbDrone.Host { private readonly IServiceProvider _serviceProvider; private readonly IConsoleService _consoleService; - private readonly IRuntimeInfo _runtimeInfo; private readonly IProcessProvider _processProvider; private readonly IRemoteAccessAdapter _remoteAccessAdapter; private readonly Logger _logger; public UtilityModeRouter(IServiceProvider serviceProvider, IConsoleService consoleService, - IRuntimeInfo runtimeInfo, IProcessProvider processProvider, IRemoteAccessAdapter remoteAccessAdapter, Logger logger) { _serviceProvider = serviceProvider; _consoleService = consoleService; - _runtimeInfo = runtimeInfo; _processProvider = processProvider; _remoteAccessAdapter = remoteAccessAdapter; _logger = logger; diff --git a/src/NzbDrone/Sonarr.csproj b/src/NzbDrone/Sonarr.csproj index 992e8755b..77a39e69c 100644 --- a/src/NzbDrone/Sonarr.csproj +++ b/src/NzbDrone/Sonarr.csproj @@ -5,7 +5,6 @@ win-x64;win-x86 true ..\NzbDrone.Host\Sonarr.ico - app.manifest true @@ -13,6 +12,7 @@ + diff --git a/src/NzbDrone/SysTray/SysTrayApp.cs b/src/NzbDrone/SysTray/SysTrayApp.cs index 4493099c7..edb0b7f42 100644 --- a/src/NzbDrone/SysTray/SysTrayApp.cs +++ b/src/NzbDrone/SysTray/SysTrayApp.cs @@ -4,9 +4,8 @@ using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.Extensions.Hosting; -using NLog; using NzbDrone.Common.EnvironmentInfo; -using NzbDrone.Common.Processes; +using NzbDrone.Core.Lifecycle; using NzbDrone.Host; namespace NzbDrone.SysTray @@ -14,28 +13,19 @@ namespace NzbDrone.SysTray public class SystemTrayApp : Form, IHostedService { private readonly IBrowserService _browserService; - private readonly IRuntimeInfo _runtimeInfo; - private readonly IProcessProvider _processProvider; + private readonly ILifecycleService _lifecycle; private readonly NotifyIcon _trayIcon = new NotifyIcon(); private readonly ContextMenuStrip _trayMenu = new ContextMenuStrip(); - public SystemTrayApp(IBrowserService browserService, IRuntimeInfo runtimeInfo, IProcessProvider processProvider) + public SystemTrayApp(IBrowserService browserService, ILifecycleService lifecycle) { _browserService = browserService; - _runtimeInfo = runtimeInfo; - _processProvider = processProvider; + _lifecycle = lifecycle; } public void Start() { - Application.ThreadException += OnThreadException; - Application.ApplicationExit += OnApplicationExit; - - Application.SetHighDpiMode(HighDpiMode.PerMonitor); - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - _trayMenu.Items.Add(new ToolStripMenuItem("Launch Browser", null, LaunchBrowser)); _trayMenu.Items.Add(new ToolStripSeparator()); _trayMenu.Items.Add(new ToolStripMenuItem("Exit", null, OnExit)); @@ -69,12 +59,6 @@ namespace NzbDrone.SysTray DisposeTrayIcon(); } - protected override void OnClosed(EventArgs e) - { - Console.WriteLine("Closing"); - base.OnClosed(e); - } - protected override void OnLoad(EventArgs e) { Visible = false; @@ -102,8 +86,7 @@ namespace NzbDrone.SysTray private void OnExit(object sender, EventArgs e) { - LogManager.Configuration = null; - Environment.Exit(0); + _lifecycle.Shutdown(); } private void LaunchBrowser(object sender, EventArgs e) @@ -117,33 +100,17 @@ namespace NzbDrone.SysTray } } - private void OnApplicationExit(object sender, EventArgs e) - { - if (_runtimeInfo.RestartPending) - { - _processProvider.SpawnNewProcess(_runtimeInfo.ExecutingApplication, "--restart --nobrowser"); - } - - DisposeTrayIcon(); - } - - private void OnThreadException(object sender, EventArgs e) - { - DisposeTrayIcon(); - } - private void DisposeTrayIcon() { - try - { - _trayIcon.Visible = false; - _trayIcon.Icon = null; - _trayIcon.Visible = false; - _trayIcon.Dispose(); - } - catch (Exception) + if (_trayIcon == null) { + return; } + + _trayIcon.Visible = false; + _trayIcon.Icon = null; + _trayIcon.Visible = false; + _trayIcon.Dispose(); } } } diff --git a/src/NzbDrone/WindowsApp.cs b/src/NzbDrone/WindowsApp.cs index a2d99a4e0..1c412d8a4 100644 --- a/src/NzbDrone/WindowsApp.cs +++ b/src/NzbDrone/WindowsApp.cs @@ -16,20 +16,22 @@ namespace NzbDrone public static void Main(string[] args) { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.SetHighDpiMode(HighDpiMode.SystemAware); + try { var startupArgs = new StartupContext(args); NzbDroneLogger.Register(startupArgs, false, true); - Bootstrap.Start(args, e => - { - e.ConfigureServices((_, s) => s.AddSingleton()); - }); + Bootstrap.Start(args, e => { e.ConfigureServices((_, s) => s.AddSingleton()); }); } catch (Exception e) { Logger.Fatal(e, "EPIC FAIL"); + var message = string.Format("{0}: {1}", e.GetType().Name, e.ToString()); MessageBox.Show($"{e.GetType().Name}: {e.Message}", buttons: MessageBoxButtons.OK, icon: MessageBoxIcon.Error, caption: "Epic Fail!"); } } diff --git a/src/NzbDrone/app.config b/src/NzbDrone/app.config deleted file mode 100644 index 2b0b69660..000000000 --- a/src/NzbDrone/app.config +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/NzbDrone/app.manifest b/src/NzbDrone/app.manifest deleted file mode 100644 index d875ce85e..000000000 --- a/src/NzbDrone/app.manifest +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - - -