New option to shutdown parent process first.

Option name = stopparentprocessfirst

Signed-off-by: Oleg Nenashev <o.v.nenashev@gmail.com>
pull/53/head
Oleg Demchenko 2014-06-20 14:43:19 +04:00 committed by Oleg Nenashev
parent d0d4266af2
commit 350fa99749
3 changed files with 65 additions and 5 deletions

46
Main.cs
View File

@ -304,16 +304,56 @@ namespace winsw
}
private void StopProcessAndChildren(int pid)
{
var childPids = GetChildPids(pid);
if (descriptor.StopParentProcessFirst)
{
StopProcess(pid);
foreach (var childPid in childPids)
{
StopProcessAndChildren(childPid);
}
}
else
{
foreach (var childPid in childPids)
{
StopProcessAndChildren(childPid);
}
StopProcess(pid);
}
}
private List<int> GetChildPids(int pid)
{
var searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid);
var childPids = new List<int>();
foreach (var mo in searcher.Get())
{
StopProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
var childProcessId = mo["ProcessID"];
WriteEvent("Found child process: " + childProcessId + " Name: " + mo["Name"]);
childPids.Add(Convert.ToInt32(childProcessId));
}
return childPids;
}
private void StopProcess(int pid)
{
WriteEvent("Stopping process " + pid);
Process proc;
try
{
proc = Process.GetProcessById(pid);
}
catch (ArgumentException)
{
WriteEvent("Process " + pid + " is already stopped");
return;
}
var proc = Process.GetProcessById(pid);
WriteEvent("Send SIGINT " + pid);
bool successful = SigIntHelper.SendSIGINTToProcess(proc,descriptor.StopTimeout);
bool successful = SigIntHelper.SendSIGINTToProcess(proc, descriptor.StopTimeout);
if (successful)
{
WriteEvent("SIGINT to" + pid + " successful");

View File

@ -292,3 +292,9 @@ Possible values are `idle`, `belownormal`, `normal`, `abovenormal`, `high`, `rea
<priority>idle</priority>
Specifying a priority higher than normal has unintended consequences. See <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.processpriorityclass(v=vs.110).aspx">MSDN discussion</a> for details. This feature is intended primarily to launch a process in a lower priority so as not to interfere with the computer's interactive usage.
###stopparentprocessfirst
Optionally specify the order of service shutdown. If true, the parent process is shutdown first. This is useful when the main process is a console, which can respond to Ctrol+C command and will gracefully shutdown child processes
```
<stopparentprocessfirst>true</stopparentprocessfirst>
```

View File

@ -28,13 +28,13 @@ namespace winsw
///
/// This string is "c:\abc\def\ghi" when the configuration XML is "c:\abc\def\ghi.xml"
/// </summary>
public readonly string BasePath;
public string BasePath { get; set; }
/// <summary>
/// The file name portion of the configuration file.
///
/// In the above example, this would be "ghi".
/// </summary>
public readonly string BaseName;
public string BaseName { get; set; }
public virtual string ExecutablePath
{
@ -584,6 +584,20 @@ namespace winsw
}
}
public bool StopParentProcessFirst
{
get
{
var value = SingleElement("stopparentprocessfirst", true);
bool result;
if (bool.TryParse(value, out result))
{
return result;
}
return false;
}
}
/// <summary>
/// Desired process priority or null if not specified.
/// </summary>