From afb43c58e288ce34737979aee746ed82d3e952ea Mon Sep 17 00:00:00 2001 From: jjasper4 Date: Mon, 19 Jan 2009 00:41:57 +0000 Subject: [PATCH] delay shutdown for service to end properly git-svn-id: https://svn.kenai.com/svn/winsw~subversion/trunk@25 c8b2a3fe-9b5b-6a51-a37e-dc31b0e308fa --- Main.cs | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/Main.cs b/Main.cs index 3dc448f..3ca1ab6 100644 --- a/Main.cs +++ b/Main.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; +using System.Runtime.InteropServices; using System.ServiceProcess; using System.Text; using System.IO; @@ -13,6 +14,28 @@ using Microsoft.Win32; 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, + } + /// /// In-memory representation of the configuration file. /// @@ -296,6 +319,10 @@ namespace winsw 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 ServiceDescriptor descriptor; private Dictionary envs; @@ -442,7 +469,7 @@ namespace winsw 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); log.WriteLine(message); @@ -496,7 +523,14 @@ namespace winsw protected override void OnStop() { - StopIt(); + try + { + StopIt(); + } + catch (Exception ex) + { + WriteEvent("Stop exception:" + ex.Message); + } } private void StopIt() @@ -529,11 +563,38 @@ namespace winsw } 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) { var ps = process.StartInfo;