/// <summary> /// Enumerates services in the specified service control manager database. /// The name and status of each service are provided. /// </summary> /// <returns> /// An IEnumerable of <see cref="ENUM_SERVICE_STATUS"/> structures that receive the name and service status information for each service in the database. /// </returns> /// <exception cref="Win32Exception">If the method fails, returning the calling thread's last-error code value.</exception> public static unsafe IEnumerable <ENUM_SERVICE_STATUS> EnumServicesStatus() { using (var scmHandle = OpenSCManager(null, null, ServiceManagerAccess.SC_MANAGER_ENUMERATE_SERVICE)) { if (scmHandle.IsInvalid) { throw new Win32Exception(); } int bufferSizeNeeded = 0; int numServicesReturned = 0; int resumeIndex = 0; if (EnumServicesStatus( scmHandle, ServiceType.SERVICE_WIN32, ServiceStateQuery.SERVICE_STATE_ALL, IntPtr.Zero, 0, ref bufferSizeNeeded, ref numServicesReturned, ref resumeIndex)) { return(Enumerable.Empty <ENUM_SERVICE_STATUS>()); } var lastError = GetLastError(); if (lastError != Win32ErrorCode.ERROR_MORE_DATA) { throw new Win32Exception(lastError); } fixed(byte *buffer = new byte[bufferSizeNeeded]) { if (!EnumServicesStatus( scmHandle, ServiceType.SERVICE_WIN32, ServiceStateQuery.SERVICE_STATE_ALL, buffer, bufferSizeNeeded, ref bufferSizeNeeded, ref numServicesReturned, ref resumeIndex)) { throw new Win32Exception(); } var result = new ENUM_SERVICE_STATUS[numServicesReturned]; byte *position = buffer; int structSize = Marshal.SizeOf(typeof(ENUM_SERVICE_STATUS)); for (int i = 0; i < numServicesReturned; i++) { result[i] = (ENUM_SERVICE_STATUS)Marshal.PtrToStructure(new IntPtr(position), typeof(ENUM_SERVICE_STATUS)); position += structSize; } return(result); } } }
internal Service(ENUM_SERVICE_STATUS status) { Name = status.lpServiceName; DisplayName = status.lpDisplayName; //ProcessId = status.serviceStatus.dwProcessId; State = (ServiceState)status.serviceStatus.dwCurrentState; }
/// <summary> /// Enumerates services in the specified service control manager database. /// The name and status of each service are provided. /// </summary> /// <returns> /// An IEnumerable of <see cref="ENUM_SERVICE_STATUS"/> structures that receive the name and service status information for each service in the database. /// </returns> /// <exception cref="Win32Exception">If the method fails, returning the calling thread's last-error code value.</exception> public static unsafe IEnumerable<ENUM_SERVICE_STATUS> EnumServicesStatus() { using (var scmHandle = OpenSCManager(null, null, ServiceManagerAccess.SC_MANAGER_ENUMERATE_SERVICE)) { if (scmHandle.IsInvalid) { throw new Win32Exception(); } int bufferSizeNeeded = 0; int numServicesReturned = 0; int resumeIndex = 0; if (EnumServicesStatus( scmHandle, ServiceType.SERVICE_WIN32, ServiceStateQuery.SERVICE_STATE_ALL, IntPtr.Zero, 0, ref bufferSizeNeeded, ref numServicesReturned, ref resumeIndex)) { return Enumerable.Empty<ENUM_SERVICE_STATUS>(); } var lastError = GetLastError(); if (lastError != Win32ErrorCode.ERROR_MORE_DATA) { throw new Win32Exception(lastError); } fixed (byte* buffer = new byte[bufferSizeNeeded]) { if (!EnumServicesStatus( scmHandle, ServiceType.SERVICE_WIN32, ServiceStateQuery.SERVICE_STATE_ALL, buffer, bufferSizeNeeded, ref bufferSizeNeeded, ref numServicesReturned, ref resumeIndex)) { throw new Win32Exception(); } var result = new ENUM_SERVICE_STATUS[numServicesReturned]; byte* position = buffer; int structSize = Marshal.SizeOf(typeof(ENUM_SERVICE_STATUS)); for (int i = 0; i < numServicesReturned; i++) { result[i] = (ENUM_SERVICE_STATUS)Marshal.PtrToStructure(new IntPtr(position), typeof(ENUM_SERVICE_STATUS)); position += structSize; } return result; } } }
EnumServicesStatusW(int hSCManager, uint dwServiceType, uint dwServiceState, ref ENUM_SERVICE_STATUS lpServices, uint cbBufSize, ref uint pcbBytesNeeded, ref uint lpServicesReturned, ref uint lpResumeHandle);
public static extern int EnumServicesStatusW(int hSCManager, uint dwServiceType, uint dwServiceState, ref ENUM_SERVICE_STATUS lpServices, uint cbBufSize, ref uint pcbBytesNeeded, ref uint lpServicesReturned, ref uint lpResumeHandle);
public static extern int EnumDependentServicesW( int hService, uint dwServiceState, ref ENUM_SERVICE_STATUS [] lpServices, uint cbBuffSize, ref uint pcbBytesNeeded, ref uint lpServicesReturned);
private static ServiceController [] GetDependentServices(string serviceName, string machineName) { IntPtr scHandle = IntPtr.Zero; IntPtr svcHandle = IntPtr.Zero; IntPtr buffer = IntPtr.Zero; try { scHandle = OpenServiceControlManager(machineName, SERVICE_MANAGER_RIGHTS.SC_MANAGER_CONNECT); svcHandle = OpenService(scHandle, serviceName, SERVICE_RIGHTS.SERVICE_ENUMERATE_DEPENDENTS); if (svcHandle == IntPtr.Zero) { throw CreateCannotOpenServiceException(serviceName, machineName); } uint bufferSize = 0; uint bytesNeeded = 0; uint servicesReturned = 0; ServiceController [] services; while (true) { if (!EnumDependentServices(svcHandle, SERVICE_STATE_REQUEST.SERVICE_STATE_ALL, buffer, bufferSize, out bytesNeeded, out servicesReturned)) { int err = Marshal.GetLastWin32Error(); if (err == ERROR_MORE_DATA) { buffer = Marshal.AllocHGlobal((int)bytesNeeded); bufferSize = bytesNeeded; } else { throw new Win32Exception(err); } } else { int iPtr = buffer.ToInt32(); services = new ServiceController [servicesReturned]; for (int i = 0; i < servicesReturned; i++) { ENUM_SERVICE_STATUS serviceStatus = (ENUM_SERVICE_STATUS)Marshal.PtrToStructure( new IntPtr(iPtr), typeof(ENUM_SERVICE_STATUS)); // TODO: use internal ctor that takes displayname too ? services [i] = new ServiceController(serviceStatus.pServiceName, machineName); // move on to the next services iPtr += ENUM_SERVICE_STATUS.SizeOf; } // we're done, so exit the loop break; } } return(services); } finally { if (scHandle != IntPtr.Zero) { CloseServiceHandle(scHandle); } if (svcHandle != IntPtr.Zero) { CloseServiceHandle(svcHandle); } if (buffer != IntPtr.Zero) { Marshal.FreeHGlobal(buffer); } } }