mirror of https://github.com/winsw/winsw
Fix service crashes
parent
e97bc5bc72
commit
1f188cf20b
|
@ -193,20 +193,28 @@ namespace WinSW.Util
|
|||
if (!AttachConsole(process.Id))
|
||||
{
|
||||
int error = Marshal.GetLastWin32Error();
|
||||
Log.Debug("Failed to attach to console. " + error switch
|
||||
switch (error)
|
||||
{
|
||||
Errors.ERROR_ACCESS_DENIED => "WinSW is already attached to a console.", // TODO: test mode
|
||||
Errors.ERROR_INVALID_HANDLE => "The process does not have a console.",
|
||||
Errors.ERROR_INVALID_PARAMETER => "The process has exited.",
|
||||
_ => new Win32Exception(error).Message // unreachable
|
||||
});
|
||||
// The process does not have a console.
|
||||
case Errors.ERROR_INVALID_HANDLE:
|
||||
return false;
|
||||
|
||||
return error == Errors.ERROR_INVALID_PARAMETER ? (bool?)null : false;
|
||||
// The process has exited.
|
||||
case Errors.ERROR_INVALID_PARAMETER:
|
||||
return null;
|
||||
|
||||
// The calling process is already attached to a console.
|
||||
case Errors.ERROR_ACCESS_DENIED:
|
||||
default:
|
||||
Log.Warn("Failed to attach to console. " + new Win32Exception(error).Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_ = SetConsoleCtrlHandler(null, true);
|
||||
// Don't call GenerateConsoleCtrlEvent immediately after SetConsoleCtrlHandler.
|
||||
// A delay was observed as of Windows 10, version 2004 and Windows Server 2019.
|
||||
_ = GenerateConsoleCtrlEvent(CtrlEvents.CTRL_C_EVENT, 0);
|
||||
_ = SetConsoleCtrlHandler(null, false);
|
||||
|
||||
bool succeeded = FreeConsole();
|
||||
Debug.Assert(succeeded);
|
||||
|
||||
|
|
|
@ -38,6 +38,10 @@ namespace WinSW.Tests
|
|||
Assert.Equal(ServiceControllerStatus.Running, controller.Status);
|
||||
Assert.True(controller.CanStop);
|
||||
|
||||
Assert.EndsWith(
|
||||
ServiceMessages.StartedSuccessfully + Environment.NewLine,
|
||||
File.ReadAllText(Path.ChangeExtension(config.FullPath, ".wrapper.log")));
|
||||
|
||||
if (Environment.GetEnvironmentVariable("System.DefinitionId") != null)
|
||||
{
|
||||
session = new InterProcessCodeCoverageSession(Helper.Name);
|
||||
|
@ -48,6 +52,10 @@ namespace WinSW.Tests
|
|||
_ = Helper.Test(new[] { "stop", config.FullPath }, config);
|
||||
controller.Refresh();
|
||||
Assert.Equal(ServiceControllerStatus.Stopped, controller.Status);
|
||||
|
||||
Assert.EndsWith(
|
||||
ServiceMessages.StoppedSuccessfully + Environment.NewLine,
|
||||
File.ReadAllText(Path.ChangeExtension(config.FullPath, ".wrapper.log")));
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
namespace WinSW
|
||||
{
|
||||
internal static class ServiceMessages
|
||||
{
|
||||
internal const string StartedSuccessfully = "Service started successfully.";
|
||||
internal const string StoppedSuccessfully = "Service stopped successfully.";
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ using WinSW.Extensions;
|
|||
using WinSW.Logging;
|
||||
using WinSW.Native;
|
||||
using WinSW.Util;
|
||||
using Messages = WinSW.ServiceMessages;
|
||||
|
||||
namespace WinSW
|
||||
{
|
||||
|
@ -206,7 +207,7 @@ namespace WinSW
|
|||
try
|
||||
{
|
||||
this.DoStart();
|
||||
this.LogMinimal("Service started successfully.");
|
||||
this.LogMinimal(Messages.StartedSuccessfully);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -220,7 +221,7 @@ namespace WinSW
|
|||
try
|
||||
{
|
||||
this.DoStop();
|
||||
this.LogMinimal("Service stopped successfully.");
|
||||
this.LogMinimal(Messages.StoppedSuccessfully);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -257,6 +258,8 @@ namespace WinSW
|
|||
{
|
||||
bool succeeded = ConsoleApis.FreeConsole();
|
||||
Debug.Assert(succeeded);
|
||||
succeeded = ConsoleApis.SetConsoleCtrlHandler(null, true);
|
||||
Debug.Assert(succeeded);
|
||||
|
||||
this.HandleFileCopies();
|
||||
|
||||
|
@ -561,7 +564,9 @@ namespace WinSW
|
|||
}
|
||||
}
|
||||
|
||||
bool succeeded = ConsoleApis.AllocConsole();
|
||||
bool succeeded = ConsoleApis.AllocConsole(); // inherited
|
||||
Debug.Assert(succeeded);
|
||||
succeeded = ConsoleApis.SetConsoleCtrlHandler(null, false); // inherited
|
||||
Debug.Assert(succeeded);
|
||||
|
||||
Process process;
|
||||
|
@ -573,6 +578,8 @@ namespace WinSW
|
|||
{
|
||||
succeeded = ConsoleApis.FreeConsole();
|
||||
Debug.Assert(succeeded);
|
||||
succeeded = ConsoleApis.SetConsoleCtrlHandler(null, true);
|
||||
Debug.Assert(succeeded);
|
||||
}
|
||||
|
||||
Log.Info($"Started process {process.Format()}.");
|
||||
|
|
Loading…
Reference in New Issue