public static void WaitForServiceStatus(this IService service, SERVICE_STATE state) { while (service.QueryStatus().dwCurrentState != state) { Thread.Sleep(10); } }
internal static extern bool EnumServicesStatusEx( SafeServiceHandle hSCManager, SC_ENUM_TYPE InfoLevel, ServiceType dwServiceType, SERVICE_STATE dwServiceState, SafeHGlobalBuffer lpServices, int cbBufSize, out int pcbBytesNeeded, out int lpServicesReturned, ref int lpResumeHandle, string pszGroupName );
/// <summary> /// Get a list of registered services. /// </summary> /// <returns>A list of running services with process IDs.</returns> private static IEnumerable <RunningService> GetServices(SERVICE_STATE service_state) { using (SafeServiceHandle scm = OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect | ServiceControlManagerAccessRights.EnumerateService)) { if (scm.IsInvalid) { throw new SafeWin32Exception(); } ServiceType service_types = ServiceType.Win32OwnProcess | ServiceType.Win32ShareProcess; if (!NtObjectUtils.IsWindows81OrLess) { service_types |= ServiceType.UserService; } const int Length = 32 * 1024; using (var buffer = new SafeHGlobalBuffer(Length)) { int resume_handle = 0; while (true) { bool ret = EnumServicesStatusEx(scm, SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO, service_types, service_state, buffer, buffer.Length, out int bytes_needed, out int services_returned, ref resume_handle, null); int error = Marshal.GetLastWin32Error(); if (!ret && error != ERROR_MORE_DATA) { throw new SafeWin32Exception(error); } ENUM_SERVICE_STATUS_PROCESS[] services = new ENUM_SERVICE_STATUS_PROCESS[services_returned]; buffer.ReadArray(0, services, 0, services_returned); foreach (var service in services) { yield return(new RunningService(service)); } if (ret) { break; } } } } }