/// <summary>
        /// Block until a service stops, is killed, or is found to be already dead.
        /// </summary>
        /// <param name="serviceName">The name of the service you would like to wait for.</param>
        /// <param name="timeout">An amount of time you would like to wait for. uint.MaxValue is the default, and it will force this thread to wait indefinitely.</param>
        public static void WaitForServiceToStop(string serviceName, uint timeout = uint.MaxValue)
        {
            // Ensure that this thread's identity is mapped, 1-to-1, with a native OS thread.
            Thread.BeginThreadAffinity();
            GCHandle notifyHandle = default(GCHandle);
            StatusChangedCallbackDelegate changeDelegate = ReceivedStatusChangedEvent;
            IntPtr hSCM     = IntPtr.Zero;
            IntPtr hService = IntPtr.Zero;

            try
            {
                hSCM = OpenSCManager(null, null, (uint)0xF003F);
                if (hSCM != IntPtr.Zero)
                {
                    hService = OpenService(hSCM, serviceName, (uint)0xF003F);
                    if (hService != IntPtr.Zero)
                    {
                        SERVICE_NOTIFY notify = new SERVICE_NOTIFY();
                        notify.dwVersion         = 2;
                        notify.pfnNotifyCallback = Marshal.GetFunctionPointerForDelegate(changeDelegate);
                        notify.ServiceStatus     = new SERVICE_STATUS_PROCESS();
                        notifyHandle             = GCHandle.Alloc(notify, GCHandleType.Pinned);
                        IntPtr pinnedNotifyStructure = notifyHandle.AddrOfPinnedObject();
                        NotifyServiceStatusChange(hService, (uint)0x00000001, pinnedNotifyStructure);
                        SleepEx(timeout, true);
                    }
                }
            }
            finally
            {
                // Clean up at the end of our operation, or if this thread is aborted.
                if (hService != IntPtr.Zero)
                {
                    CloseServiceHandle(hService);
                }
                if (hSCM != IntPtr.Zero)
                {
                    CloseServiceHandle(hSCM);
                }
                GC.KeepAlive(changeDelegate);
                if (notifyHandle != default(GCHandle))
                {
                    notifyHandle.Free();
                }
                Thread.EndThreadAffinity();
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Block until a service stops or is found to be already dead.
        /// </summary>
        /// <param name="serviceName">The name of the service you would like to wait for.</param>
        public static void WaitForServiceToStop(string serviceName)
        {
            IntPtr hSCM = OpenSCManager(null, null, (uint)0xF003F);

            if (hSCM != IntPtr.Zero)
            {
                IntPtr hService = OpenService(hSCM, serviceName, (uint)0xF003F);
                if (hService != IntPtr.Zero)
                {
                    StatusChangedCallbackDelegate changeDelegate = ReceivedStatusChangedEvent;
                    SERVICE_NOTIFY notify = new SERVICE_NOTIFY();
                    notify.dwVersion         = 2;
                    notify.pfnNotifyCallback = Marshal.GetFunctionPointerForDelegate(changeDelegate);
                    notify.ServiceStatus     = new SERVICE_STATUS_PROCESS();
                    GCHandle notifyHandle             = GCHandle.Alloc(notify, GCHandleType.Pinned);
                    IntPtr   unmanagedNotifyStructure = notifyHandle.AddrOfPinnedObject();
                    NotifyServiceStatusChange(hService, (uint)0x00000001, unmanagedNotifyStructure);
                    SleepEx(uint.MaxValue, true);
                    notifyHandle.Free();
                    CloseServiceHandle(hService);
                }
                CloseServiceHandle(hSCM);
            }
        }