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
|
try
|
||||||
{
|
{
|
||||||
var proc = Process.GetProcessById(pid);
|
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)
|
catch (ArgumentException)
|
||||||
{
|
{
|
||||||
|
|
|
@ -561,5 +561,15 @@ namespace winsw
|
||||||
return !string.IsNullOrEmpty(serviceAccountDomain) && !string.IsNullOrEmpty(serviceAccountName);
|
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>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProductVersion>9.0.21022</ProductVersion>
|
<ProductVersion>9.0.30729</ProductVersion>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
<ProjectGuid>{0DE77F55-ADE5-43C1-999A-0BC81153B039}</ProjectGuid>
|
<ProjectGuid>{0DE77F55-ADE5-43C1-999A-0BC81153B039}</ProjectGuid>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
|
@ -56,6 +56,7 @@
|
||||||
<Compile Include="PeriodicRollingCalendar.cs" />
|
<Compile Include="PeriodicRollingCalendar.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="ServiceDescriptor.cs" />
|
<Compile Include="ServiceDescriptor.cs" />
|
||||||
|
<Compile Include="SigIntHelper.cs" />
|
||||||
<Compile Include="Wmi.cs" />
|
<Compile Include="Wmi.cs" />
|
||||||
<Compile Include="WmiSchema.cs" />
|
<Compile Include="WmiSchema.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
Loading…
Reference in New Issue