< Summary

Information
Class: NtpServiceLibrary.ServiceStatus
Assembly: NtpServiceLibrary
File(s): D:\a\ntp-service\ntp-service\NtpServiceLibrary\ServiceState.cs
Line coverage
100%
Covered lines: 24
Uncovered lines: 0
Coverable lines: 24
Total lines: 124
Line coverage: 100%
Branch coverage
66%
Covered branches: 4
Total branches: 6
Branch coverage: 66.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%22100%
GetInstance(...)100%22100%
SetProvider(...)50%22100%
ClearInstance()100%11100%
Set(...)100%11100%

File(s)

D:\a\ntp-service\ntp-service\NtpServiceLibrary\ServiceState.cs

#LineLine coverage
 1using System.Runtime.InteropServices;
 2
 3namespace NtpServiceLibrary
 4{
 5    /// <summary>
 6    /// Represents possible states of a Windows service.
 7    /// </summary>
 8    public enum ServiceState
 9    {
 10        /// <summary>Service is stopped.</summary>
 11        SERVICE_STOPPED = 0x00000001,
 12        /// <summary>Service is starting.</summary>
 13        SERVICE_START_PENDING = 0x00000002,
 14        /// <summary>Service is stopping.</summary>
 15        SERVICE_STOP_PENDING = 0x00000003,
 16        /// <summary>Service is running.</summary>
 17        SERVICE_RUNNING = 0x00000004,
 18        /// <summary>Service is resuming from a paused state.</summary>
 19        SERVICE_CONTINUE_PENDING = 0x00000005,
 20        /// <summary>Service is pausing.</summary>
 21        SERVICE_PAUSE_PENDING = 0x00000006,
 22        /// <summary>Service is paused.</summary>
 23        SERVICE_PAUSED = 0x00000007,
 24    }
 25
 26    public interface IServiceStatusProvider
 27    {
 28        bool SetServiceStatus(System.IntPtr handle, ref ServiceStateInfo serviceStatus);
 29    }
 30
 31    public class SystemServiceStatusProvider : IServiceStatusProvider
 32    {
 33        [DllImport("advapi32.dll", SetLastError = true, EntryPoint = "SetServiceStatus")]
 34        public static extern bool _SetServiceStatus(System.IntPtr handle, ref ServiceStateInfo serviceStatus);
 35        public bool SetServiceStatus(System.IntPtr handle, ref ServiceStateInfo serviceStatus) => _SetServiceStatus(hand
 36    }
 37
 38    /// <summary>
 39    /// Contains information about the current status of a Windows service.
 40    /// Used for interop with the Windows Service Control Manager.
 41    /// </summary>
 42    [StructLayout(LayoutKind.Sequential)]
 43    public struct ServiceStateInfo
 44    {
 45        /// <summary>Type of the service.</summary>
 46        public int dwServiceType;
 47        /// <summary>Current state of the service.</summary>
 48        public ServiceState dwCurrentState;
 49        /// <summary>Controls accepted by the service.</summary>
 50        public int dwControlsAccepted;
 51        /// <summary>Win32 exit code.</summary>
 52        public int dwWin32ExitCode;
 53        /// <summary>Service-specific exit code.</summary>
 54        public int dwServiceSpecificExitCode;
 55        /// <summary>Checkpoint value for lengthy operations.</summary>
 56        public int dwCheckPoint;
 57        /// <summary>Estimated time required for a pending operation, in milliseconds.</summary>
 58        public int dwWaitHint;
 59    };
 60
 61    /// <summary>
 62    /// Provides methods for updating the service status with the Windows Service Control Manager.
 63    /// </summary>
 64    public class ServiceStatus
 65    {
 66        private static ServiceStatus _instance = null;
 67        private ServiceStateInfo _serviceStateInfo;
 68        private IServiceStatusProvider _provider;
 69
 70        /// <summary>
 71        /// Initializes a new instance of the <see cref="ServiceStatus"/> class.
 72        /// </summary>
 673        private ServiceStatus(IServiceStatusProvider provider)
 674        {
 675            _provider = provider ?? new SystemServiceStatusProvider();
 676            _serviceStateInfo = new ServiceStateInfo
 677            {
 678                dwWaitHint = 100000
 679            };
 680        }
 81
 82        /// <summary>
 83        /// Gets the singleton instance of <see cref="ServiceStatus"/>.
 84        /// </summary>
 85        /// <returns>The singleton instance.</returns>
 86        private static ServiceStatus GetInstance(IServiceStatusProvider provider)
 3287        {
 3288            if (_instance == null)
 689                _instance = new ServiceStatus(provider);
 3290            return _instance;
 3291        }
 92
 93        /// <summary>
 94        /// Sets the provider.
 95        /// </summary>
 96        /// <param name="provider">Service status manipulation object.</param>
 97        public static void SetProvider(IServiceStatusProvider provider)
 298        {
 299            _instance._provider = provider ?? new SystemServiceStatusProvider();
 2100        }
 101
 102        /// <summary>
 103        /// Deletes the singleton instance (e.g. for use in testing).
 104        /// </summary>
 105        internal static void ClearInstance()
 6106        {
 6107            _instance = null;
 6108        }
 109
 110        /// <summary>
 111        /// Sets the current service status using the Windows API.
 112        /// </summary>
 113        /// <param name="handle">A handle to the service status.</param>
 114        /// <param name="state">The new state to set.</param>
 115        /// <param name="provider">Service status manipulation object.</param>
 116        /// <returns>True if the status was set successfully; otherwise, false.</returns>
 117        public static bool Set(System.IntPtr handle, ServiceState state, IServiceStatusProvider provider=null)
 32118        {
 32119            var instance = GetInstance(provider);
 32120            instance._serviceStateInfo.dwCurrentState = state;
 32121            return instance._provider.SetServiceStatus(handle, ref instance._serviceStateInfo);
 32122        }
 123    }
 124}