Fix termination

pull/595/head
NextTurn 2020-07-22 00:00:00 +08:00 committed by Next Turn
parent db842409f1
commit f02e63486b
2 changed files with 34 additions and 67 deletions

View File

@ -87,25 +87,18 @@ namespace WinSW.Util
bool exited = result.Value; bool exited = result.Value;
if (!exited) if (!exited)
{ {
bool sent = result.Key;
if (sent)
{
Logger.Warn("Process " + process.Id + " did not respond to Ctrl+C signal - Killing as fallback");
}
try try
{ {
bool sent = result.Key;
if (sent)
{
Logger.Warn("Process " + process.Id + " did not respond to Ctrl+C signal - Killing as fallback");
}
process.Kill(); process.Kill();
} }
catch (Exception ex) catch when (process.HasExited)
{ {
if (!process.HasExited)
{
throw;
}
// Process already exited.
Logger.Warn("Ignoring exception from killing process because it has exited", ex);
} }
} }
@ -146,7 +139,7 @@ namespace WinSW.Util
Dictionary<string, string>? envVars = null, Dictionary<string, string>? envVars = null,
string? workingDirectory = null, string? workingDirectory = null,
ProcessPriorityClass? priority = null, ProcessPriorityClass? priority = null,
ProcessCompletionCallback? callback = null, Action<Process>? callback = null,
bool redirectStdin = true, bool redirectStdin = true,
LogHandler? logHandler = null, LogHandler? logHandler = null,
bool hideWindow = false) bool hideWindow = false)
@ -193,11 +186,11 @@ namespace WinSW.Util
// monitor the completion of the process // monitor the completion of the process
if (callback != null) if (callback != null)
{ {
processToStart.Exited += (_, _) => processToStart.Exited += (sender, _) =>
{ {
try try
{ {
callback(processToStart); callback((Process)sender!);
} }
catch (Exception e) catch (Exception e)
{ {
@ -209,6 +202,4 @@ namespace WinSW.Util
} }
} }
} }
public delegate void ProcessCompletionCallback(Process process);
} }

View File

@ -301,16 +301,9 @@ namespace WinSW
if (stopArguments is null) if (stopArguments is null)
{ {
try Log.Debug("ProcessKill " + this.process.Id);
{ ProcessHelper.StopProcessTree(this.process, this.descriptor.StopTimeout);
Log.Debug("ProcessKill " + this.process.Id); this.ExtensionManager.FireOnProcessTerminated(this.process);
ProcessHelper.StopProcessTree(this.process, this.descriptor.StopTimeout);
this.ExtensionManager.FireOnProcessTerminated(this.process);
}
catch (InvalidOperationException)
{
// already terminated
}
} }
else else
{ {
@ -358,19 +351,12 @@ namespace WinSW
effectiveProcessWaitSleepTime = (int)this.descriptor.SleepTime.TotalMilliseconds; effectiveProcessWaitSleepTime = (int)this.descriptor.SleepTime.TotalMilliseconds;
} }
try // WriteEvent("WaitForProcessToExit [start]");
{
// WriteEvent("WaitForProcessToExit [start]");
while (!processoWait.WaitForExit(effectiveProcessWaitSleepTime)) while (!processoWait.WaitForExit(effectiveProcessWaitSleepTime))
{
this.SignalShutdownPending();
// WriteEvent("WaitForProcessToExit [repeat]");
}
}
catch (InvalidOperationException)
{ {
// already terminated this.SignalShutdownPending();
// WriteEvent("WaitForProcessToExit [repeat]");
} }
// WriteEvent("WaitForProcessToExit [finished]"); // WriteEvent("WaitForProcessToExit [finished]");
@ -405,37 +391,27 @@ namespace WinSW
private void StartProcess(Process processToStart, string arguments, string executable, LogHandler? logHandler, bool redirectStdin) private void StartProcess(Process processToStart, string arguments, string executable, LogHandler? logHandler, bool redirectStdin)
{ {
// Define handler of the completed process // Define handler of the completed process
void OnProcessCompleted(Process proc) void OnProcessCompleted(Process process)
{ {
string msg = processToStart.Id + " - " + processToStart.StartInfo.FileName + " " + processToStart.StartInfo.Arguments; string msg = process.Id + " - " + process.StartInfo.FileName + " " + process.StartInfo.Arguments;
try
{
if (this.orderlyShutdown)
{
this.LogEvent("Child process [" + msg + "] terminated with " + proc.ExitCode, EventLogEntryType.Information);
}
else
{
this.LogEvent("Child process [" + msg + "] finished with " + proc.ExitCode, EventLogEntryType.Warning);
// if we finished orderly, report that to SCM. if (this.orderlyShutdown)
// by not reporting unclean shutdown, we let Windows SCM to decide if it wants to {
// restart the service automatically this.LogEvent("Child process [" + msg + "] terminated with " + process.ExitCode, EventLogEntryType.Information);
if (proc.ExitCode == 0) }
{ else
this.SignalShutdownComplete(); {
} this.LogEvent("Child process [" + msg + "] finished with " + process.ExitCode, EventLogEntryType.Warning);
Environment.Exit(proc.ExitCode); // if we finished orderly, report that to SCM.
// by not reporting unclean shutdown, we let Windows SCM to decide if it wants to
// restart the service automatically
if (process.ExitCode == 0)
{
this.SignalShutdownComplete();
} }
}
catch (InvalidOperationException ioe) Environment.Exit(process.ExitCode);
{
this.LogEvent("WaitForExit " + ioe.Message);
}
finally
{
proc.Dispose();
} }
} }