예제 #1
0
        public void NotifyServiceStatusChangeTest()
        {
            var cnt = 0;
            ManualResetEvent evt;

            Thread.BeginThreadAffinity();
            try
            {
                PFN_SC_NOTIFY_CALLBACK callback = ChangeDelegate;
                var svcNotify = new SERVICE_NOTIFY_2
                {
                    dwVersion         = 2,
                    pfnNotifyCallback = Marshal.GetFunctionPointerForDelegate(callback),
                };
                using (evt = new ManualResetEvent(false))
                    using (var pNotify = new PinnedObject(svcNotify))
                    {
                        Assert.That(NotifyServiceStatusChange(hSvc, SERVICE_NOTIFY_FLAGS.SERVICE_NOTIFY_PAUSED | SERVICE_NOTIFY_FLAGS.SERVICE_NOTIFY_PAUSE_PENDING | SERVICE_NOTIFY_FLAGS.SERVICE_NOTIFY_CONTINUE_PENDING, pNotify), ResultIs.Successful);
                        var th = new Thread(ThreadExec);
                        th.Start((SC_HANDLE)hSvc);
                        while (!evt.WaitOne(5))
                        {
                            ;
                        }
                        Assert.That(cnt, Is.GreaterThan(0));
                    }
            }
            finally
            {
                Thread.EndThreadAffinity();
            }

            void ChangeDelegate(IntPtr pParameter)
            {
                System.Diagnostics.Debug.WriteLine(pParameter.ToStructure <SERVICE_NOTIFY_2>().ServiceStatus.dwCurrentState);
                cnt++;
            }

            void ThreadExec(object handle)
            {
                var svc = (SC_HANDLE)handle;

                System.Diagnostics.Debug.WriteLine("Pausing...");
                if (!ControlService(svc, ServiceControl.SERVICE_CONTROL_PAUSE, out _))
                {
                    System.Diagnostics.Debug.WriteLine($"Pausing failed: {Win32Error.GetLastError()}");
                }
                WaitForServiceStatus(svc, ServiceState.SERVICE_PAUSED);
                System.Diagnostics.Debug.WriteLine("Continuing...");
                if (!ControlService(svc, ServiceControl.SERVICE_CONTROL_CONTINUE, out _))
                {
                    System.Diagnostics.Debug.WriteLine($"Pausing failed: {Win32Error.GetLastError()}");
                }
                WaitForServiceStatus(svc, ServiceState.SERVICE_RUNNING);
                System.Diagnostics.Debug.WriteLine("Running...");
                evt.Set();
            }
        }
예제 #2
0
        public void NotifyServiceStatusChangeTest()
        {
            var svcNotify = new SERVICE_NOTIFY_2
            {
                dwVersion         = 2,
                pfnNotifyCallback = ChangeDelegate
            };

            Thread.BeginThreadAffinity();
            var ret = NotifyServiceStatusChange(hSvc, SERVICE_NOTIFY_FLAGS.SERVICE_NOTIFY_PAUSED | SERVICE_NOTIFY_FLAGS.SERVICE_NOTIFY_PAUSE_PENDING | SERVICE_NOTIFY_FLAGS.SERVICE_NOTIFY_CONTINUE_PENDING, ref svcNotify);

            if (ret.Failed)
            {
                TestContext.WriteLine(ret);
            }
            Assert.That(ret.Succeeded, Is.True);
            new Thread(ThreadExec).Start();
            Kernel32.SleepEx(10000, true);
            Thread.EndThreadAffinity();

            void ChangeDelegate(ref SERVICE_NOTIFY_2 pParameter)
            {
                TestContext.WriteLine(pParameter.ServiceStatus.dwCurrentState);
            }

            void ThreadExec()
            {
                using (var mgr = OpenSCManager(null, null, ScManagerAccessTypes.SC_MANAGER_ALL_ACCESS))
                {
                    if (!mgr.IsInvalid)
                    {
                        using (var svc = OpenService(hSvcMgr, svcName, ServiceAccessTypes.SERVICE_ALL_ACCESS))
                        {
                            if (!svc.IsInvalid)
                            {
                                TestContext.WriteLine("Pausing...");
                                ControlService(svc, ServiceControl.SERVICE_CONTROL_PAUSE, out _);
                                Thread.Sleep(3000);
                                TestContext.WriteLine("Continuing...");
                                ControlService(svc, ServiceControl.SERVICE_CONTROL_CONTINUE, out _);
                                Thread.Sleep(3000);
                            }
                        }
                    }
                }
            }
        }