mirror of https://github.com/winsw/winsw
Add option to send a SIGINT to the process being wrapped
parent
ab4a373038
commit
1ed045b817
20
Main.cs
20
Main.cs
|
@ -340,7 +340,25 @@ namespace winsw
|
|||
try
|
||||
{
|
||||
var proc = Process.GetProcessById(pid);
|
||||
proc.Kill();
|
||||
if (descriptor.SendSIGINT)
|
||||
{
|
||||
WriteEvent("Send SIGINT " + process.Id);
|
||||
bool successful = SigIntHelper.SendSIGINTToProcess(proc);
|
||||
if (successful)
|
||||
{
|
||||
WriteEvent("SIGINT to" + process.Id + " successful");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteEvent("SIGINT to " + process.Id + " failed - Killing as fallback");
|
||||
proc.Kill();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteEvent("ProcessKill " + process.Id);
|
||||
proc.Kill();
|
||||
}
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
|
|
|
@ -561,5 +561,15 @@ namespace winsw
|
|||
return !string.IsNullOrEmpty(serviceAccountDomain) && !string.IsNullOrEmpty(serviceAccountName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if the service can interact with the desktop.
|
||||
/// </summary>
|
||||
public bool SendSIGINT
|
||||
{
|
||||
get
|
||||
{
|
||||
return dom.SelectSingleNode("//sendsigint") != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace winsw
|
||||
{
|
||||
public static class SigIntHelper
|
||||
{
|
||||
private const string KERNEL32 = "kernel32.dll";
|
||||
|
||||
[DllImport(KERNEL32, SetLastError = true)]
|
||||
private static extern bool AttachConsole(uint dwProcessId);
|
||||
|
||||
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true)]
|
||||
private static extern bool FreeConsole();
|
||||
|
||||
[DllImport(KERNEL32)]
|
||||
private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
|
||||
// Delegate type to be used as the Handler Routine for SCCH
|
||||
private delegate Boolean ConsoleCtrlDelegate(CtrlTypes CtrlType);
|
||||
|
||||
// Enumerated type for the control messages sent to the handler routine
|
||||
private enum CtrlTypes : uint
|
||||
{
|
||||
CTRL_C_EVENT = 0,
|
||||
CTRL_BREAK_EVENT,
|
||||
CTRL_CLOSE_EVENT,
|
||||
CTRL_LOGOFF_EVENT = 5,
|
||||
CTRL_SHUTDOWN_EVENT
|
||||
}
|
||||
|
||||
[DllImport(KERNEL32)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);
|
||||
|
||||
/// <summary>
|
||||
/// Uses the native funciton "AttachConsole" to attach the thread to the executing process to try to trigger a CTRL_C event (SIGINT). If the application
|
||||
/// doesn't honor the event and shut down gracefully, the. wait period will time out after 15 seconds.
|
||||
/// </summary>
|
||||
/// <param name="process">The process to attach to and send the SIGINT</param>
|
||||
/// <returns>True if the process shut down successfully to the SIGINT, false if it did not.</returns>
|
||||
public static bool SendSIGINTToProcess(Process process)
|
||||
{
|
||||
if (AttachConsole((uint)process.Id))
|
||||
{
|
||||
//Disable Ctrl-C handling for our program
|
||||
SetConsoleCtrlHandler(null, true);
|
||||
GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);
|
||||
|
||||
process.WaitForExit(15000);
|
||||
|
||||
return process.HasExited;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{0DE77F55-ADE5-43C1-999A-0BC81153B039}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
|
@ -56,6 +56,7 @@
|
|||
<Compile Include="PeriodicRollingCalendar.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ServiceDescriptor.cs" />
|
||||
<Compile Include="SigIntHelper.cs" />
|
||||
<Compile Include="Wmi.cs" />
|
||||
<Compile Include="WmiSchema.cs" />
|
||||
</ItemGroup>
|
||||
|
|
Loading…
Reference in New Issue