mirror of https://github.com/winsw/winsw
delay shutdown for service to end properly
git-svn-id: https://svn.kenai.com/svn/winsw~subversion/trunk@25 c8b2a3fe-9b5b-6a51-a37e-dc31b0e308faremotes/git-svn
parent
7f8ceb3f45
commit
afb43c58e2
67
Main.cs
67
Main.cs
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -13,6 +14,28 @@ using Microsoft.Win32;
|
||||||
|
|
||||||
namespace winsw
|
namespace winsw
|
||||||
{
|
{
|
||||||
|
public struct SERVICE_STATUS
|
||||||
|
{
|
||||||
|
public int serviceType;
|
||||||
|
public int currentState;
|
||||||
|
public int controlsAccepted;
|
||||||
|
public int win32ExitCode;
|
||||||
|
public int serviceSpecificExitCode;
|
||||||
|
public int checkPoint;
|
||||||
|
public int waitHint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum State
|
||||||
|
{
|
||||||
|
SERVICE_STOPPED = 0x00000001,
|
||||||
|
SERVICE_START_PENDING = 0x00000002,
|
||||||
|
SERVICE_STOP_PENDING = 0x00000003,
|
||||||
|
SERVICE_RUNNING = 0x00000004,
|
||||||
|
SERVICE_CONTINUE_PENDING = 0x00000005,
|
||||||
|
SERVICE_PAUSE_PENDING = 0x00000006,
|
||||||
|
SERVICE_PAUSED = 0x00000007,
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// In-memory representation of the configuration file.
|
/// In-memory representation of the configuration file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -296,6 +319,10 @@ namespace winsw
|
||||||
|
|
||||||
public class WrapperService : ServiceBase
|
public class WrapperService : ServiceBase
|
||||||
{
|
{
|
||||||
|
[DllImport("ADVAPI32.DLL", EntryPoint = "SetServiceStatus")]
|
||||||
|
private static extern bool SetServiceStatus(IntPtr hServiceStatus, ref SERVICE_STATUS lpServiceStatus);
|
||||||
|
private SERVICE_STATUS wrapperServiceStatus;
|
||||||
|
|
||||||
private Process process = new Process();
|
private Process process = new Process();
|
||||||
private ServiceDescriptor descriptor;
|
private ServiceDescriptor descriptor;
|
||||||
private Dictionary<string, string> envs;
|
private Dictionary<string, string> envs;
|
||||||
|
@ -442,7 +469,7 @@ namespace winsw
|
||||||
|
|
||||||
private void WriteEvent(String message)
|
private void WriteEvent(String message)
|
||||||
{
|
{
|
||||||
string logfilename = Path.Combine(descriptor.LogDirectory, descriptor.BaseName + ".log");
|
string logfilename = Path.Combine(descriptor.LogDirectory, descriptor.BaseName + ".wrapper.log");
|
||||||
StreamWriter log = new StreamWriter(logfilename, true);
|
StreamWriter log = new StreamWriter(logfilename, true);
|
||||||
|
|
||||||
log.WriteLine(message);
|
log.WriteLine(message);
|
||||||
|
@ -495,9 +522,16 @@ namespace winsw
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnStop()
|
protected override void OnStop()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
StopIt();
|
StopIt();
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
WriteEvent("Stop exception:" + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void StopIt()
|
private void StopIt()
|
||||||
{
|
{
|
||||||
|
@ -529,11 +563,38 @@ namespace winsw
|
||||||
}
|
}
|
||||||
|
|
||||||
StartProcess(stopProcess, stoparguments, executable);
|
StartProcess(stopProcess, stoparguments, executable);
|
||||||
// stopProcess.WaitForExit();
|
|
||||||
process.WaitForExit();
|
WaitForProcessToExit(process);
|
||||||
|
WaitForProcessToExit(stopProcess);
|
||||||
|
// Console.Beep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void WaitForProcessToExit(Process process)
|
||||||
|
{
|
||||||
|
SignalShutdownPending();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (process.WaitForExit(3000))
|
||||||
|
{
|
||||||
|
SignalShutdownPending();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
// already terminated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SignalShutdownPending()
|
||||||
|
{
|
||||||
|
IntPtr handle = this.ServiceHandle;
|
||||||
|
wrapperServiceStatus.checkPoint++;
|
||||||
|
wrapperServiceStatus.waitHint = 5000;
|
||||||
|
SetServiceStatus(handle, ref wrapperServiceStatus);
|
||||||
|
}
|
||||||
|
|
||||||
private void StartProcess(Process process, string arguments, String executable)
|
private void StartProcess(Process process, string arguments, String executable)
|
||||||
{
|
{
|
||||||
var ps = process.StartInfo;
|
var ps = process.StartInfo;
|
||||||
|
|
Loading…
Reference in New Issue