mirror of https://github.com/winsw/winsw
New option to shutdown parent process first.
Option name = stopparentprocessfirst Signed-off-by: Oleg Nenashev <o.v.nenashev@gmail.com>pull/53/head
parent
d0d4266af2
commit
350fa99749
46
Main.cs
46
Main.cs
|
@ -304,16 +304,56 @@ namespace winsw
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StopProcessAndChildren(int pid)
|
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 searcher = new ManagementObjectSearcher("Select * From Win32_Process Where ParentProcessID=" + pid);
|
||||||
|
var childPids = new List<int>();
|
||||||
foreach (var mo in searcher.Get())
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
var proc = Process.GetProcessById(pid);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
WriteEvent("Send SIGINT " + pid);
|
WriteEvent("Send SIGINT " + pid);
|
||||||
bool successful = SigIntHelper.SendSIGINTToProcess(proc,descriptor.StopTimeout);
|
bool successful = SigIntHelper.SendSIGINTToProcess(proc, descriptor.StopTimeout);
|
||||||
if (successful)
|
if (successful)
|
||||||
{
|
{
|
||||||
WriteEvent("SIGINT to" + pid + " successful");
|
WriteEvent("SIGINT to" + pid + " successful");
|
||||||
|
|
|
@ -292,3 +292,9 @@ Possible values are `idle`, `belownormal`, `normal`, `abovenormal`, `high`, `rea
|
||||||
<priority>idle</priority>
|
<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.
|
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>
|
||||||
|
```
|
||||||
|
|
|
@ -28,13 +28,13 @@ namespace winsw
|
||||||
///
|
///
|
||||||
/// This string is "c:\abc\def\ghi" when the configuration XML is "c:\abc\def\ghi.xml"
|
/// This string is "c:\abc\def\ghi" when the configuration XML is "c:\abc\def\ghi.xml"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly string BasePath;
|
public string BasePath { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The file name portion of the configuration file.
|
/// The file name portion of the configuration file.
|
||||||
///
|
///
|
||||||
/// In the above example, this would be "ghi".
|
/// In the above example, this would be "ghi".
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly string BaseName;
|
public string BaseName { get; set; }
|
||||||
|
|
||||||
public virtual string ExecutablePath
|
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>
|
/// <summary>
|
||||||
/// Desired process priority or null if not specified.
|
/// Desired process priority or null if not specified.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Reference in New Issue