From d1ae60975e70dc8515abd2a828810a650acaae28 Mon Sep 17 00:00:00 2001 From: Next Turn <45985406+NextTurn@users.noreply.github.com> Date: Wed, 9 Dec 2020 01:14:27 +0800 Subject: [PATCH] Backport diagnosability updates (#736) --- src/WinSW.Core/Util/ProcessHelper.cs | 9 ++- src/WinSW/Program.cs | 12 +++- src/WinSW/WrapperService.cs | 90 +++++++++++++++------------- 3 files changed, 68 insertions(+), 43 deletions(-) diff --git a/src/WinSW.Core/Util/ProcessHelper.cs b/src/WinSW.Core/Util/ProcessHelper.cs index a2385b2..60240d9 100644 --- a/src/WinSW.Core/Util/ProcessHelper.cs +++ b/src/WinSW.Core/Util/ProcessHelper.cs @@ -187,7 +187,14 @@ namespace WinSW.Util if (priority != null) { - processToStart.PriorityClass = priority.Value; + try + { + processToStart.PriorityClass = priority.Value; + } + catch (InvalidOperationException) + { + // exited + } } // Redirect logs if required diff --git a/src/WinSW/Program.cs b/src/WinSW/Program.cs index 380fae4..ab7beb6 100644 --- a/src/WinSW/Program.cs +++ b/src/WinSW/Program.cs @@ -21,7 +21,6 @@ using log4net.Layout; using WinSW.Configuration; using WinSW.Logging; using WinSW.Native; -using WinSW.Util; using WMI; using ServiceType = WMI.ServiceType; @@ -74,7 +73,16 @@ namespace WinSW if (!inConsoleMode) { Log.Debug("Starting WinSW in service mode"); - ServiceBase.Run(new WrapperService(descriptor)); + using var service = new WrapperService(descriptor); + try + { + ServiceBase.Run(service); + } + catch + { + // handled in OnStart + } + return; } diff --git a/src/WinSW/WrapperService.cs b/src/WinSW/WrapperService.cs index f5eb12f..558bc0c 100644 --- a/src/WinSW/WrapperService.cs +++ b/src/WinSW/WrapperService.cs @@ -43,7 +43,7 @@ namespace WinSW /// so don't try to kill us when the child exits. /// private bool orderlyShutdown; - private bool systemShuttingdown; + private bool shuttingdown; /// /// Version of Windows service wrapper @@ -56,7 +56,7 @@ namespace WinSW /// /// Indicates that the system is shutting down. /// - public bool IsShuttingDown => this.systemShuttingdown; + public bool IsShuttingDown => this.shuttingdown; public WrapperService(IWinSWConfiguration descriptor) { @@ -67,7 +67,7 @@ namespace WinSW this.CanStop = true; this.CanPauseAndContinue = false; this.AutoLog = true; - this.systemShuttingdown = false; + this.shuttingdown = false; // Register the event log provider eventLogProvider.Service = this; @@ -144,7 +144,7 @@ namespace WinSW public void LogEvent(string message) { - if (this.systemShuttingdown) + if (this.shuttingdown) { /* NOP - cannot call EventLog because of shutdown. */ } @@ -163,7 +163,7 @@ namespace WinSW public void LogEvent(string message, EventLogEntryType type) { - if (this.systemShuttingdown) + if (this.shuttingdown) { /* NOP - cannot call EventLog because of shutdown. */ } @@ -179,8 +179,51 @@ namespace WinSW } } } + internal void RaiseOnStart(string[] args) => this.OnStart(args); + + internal void RaiseOnStop() => this.OnStop(); protected override void OnStart(string[] args) + { + try + { + this.DoStart(); + } + catch (Exception e) + { + Log.Error("Failed to start service.", e); + throw; + } + } + + protected override void OnStop() + { + try + { + this.DoStop(); + } + catch (Exception e) + { + Log.Error("Failed to stop service.", e); + throw; + } + } + + protected override void OnShutdown() + { + try + { + this.shuttingdown = true; + this.DoStop(); + } + catch (Exception e) + { + Log.Error("Failed to shut down service.", e); + throw; + } + } + + private void DoStart() { bool succeeded = ConsoleApis.SetConsoleCtrlHandler(null, true); Debug.Assert(succeeded); @@ -293,43 +336,10 @@ namespace WinSW this.process.StandardInput.Close(); // nothing for you to read! } - protected override void OnShutdown() - { - // WriteEvent("OnShutdown"); - - try - { - this.systemShuttingdown = true; - this.StopIt(); - } - catch (Exception ex) - { - Log.Error("Shutdown exception", ex); - } - } - - protected override void OnStop() - { - // WriteEvent("OnStop"); - - try - { - this.StopIt(); - } - catch (Exception ex) - { - Log.Error("Cannot stop exception", ex); - } - } - - internal void RaiseOnStart(string[] args) => this.OnStart(args); - - internal void RaiseOnStop() => this.OnStop(); - /// /// Called when we are told by Windows SCM to exit. /// - private void StopIt() + private void DoStop() { string? stopArguments = this.descriptor.StopArguments; this.LogEvent("Stopping " + this.descriptor.Id); @@ -371,7 +381,7 @@ namespace WinSW // Stop extensions this.ExtensionManager.FireBeforeWrapperStopped(); - if (this.systemShuttingdown && this.descriptor.BeepOnShutdown) + if (this.shuttingdown && this.descriptor.BeepOnShutdown) { Console.Beep(); }