/// Used by the GetServicesInGroup method. private ServiceController(string machineName, Interop.ENUM_SERVICE_STATUS_PROCESS status) { if (!CheckMachineName(machineName)) { throw new ArgumentException(SR.Format(SR.BadMachineName, machineName)); } _machineName = machineName; _name = status.serviceName; _displayName = status.displayName; _commandsAccepted = status.controlsAccepted; _status = (ServiceControllerStatus)status.currentState; _type = status.serviceType; _statusGenerated = true; }
/// Helper for GetDevices, GetServices, and ServicesDependedOn private static T[] GetServices <T>(string machineName, int serviceType, string group, Func <Interop.ENUM_SERVICE_STATUS_PROCESS, T> selector) { IntPtr databaseHandle = IntPtr.Zero; IntPtr memory = IntPtr.Zero; int bytesNeeded; int servicesReturned; int resumeHandle = 0; T[] services; try { databaseHandle = GetDataBaseHandleWithEnumerateAccess(machineName); Interop.mincore.EnumServicesStatusEx( databaseHandle, Interop.SC_ENUM_PROCESS_INFO, serviceType, Interop.STATUS_ALL, IntPtr.Zero, 0, out bytesNeeded, out servicesReturned, ref resumeHandle, group); memory = Marshal.AllocHGlobal((IntPtr)bytesNeeded); // // Get the set of services // Interop.mincore.EnumServicesStatusEx( databaseHandle, Interop.SC_ENUM_PROCESS_INFO, serviceType, Interop.STATUS_ALL, memory, bytesNeeded, out bytesNeeded, out servicesReturned, ref resumeHandle, group); // // Go through the block of memory it returned to us and select the results // services = new T[servicesReturned]; for (int i = 0; i < servicesReturned; i++) { IntPtr structPtr = (IntPtr)((long)memory + (i * Marshal.SizeOf <Interop.ENUM_SERVICE_STATUS_PROCESS>())); Interop.ENUM_SERVICE_STATUS_PROCESS status = new Interop.ENUM_SERVICE_STATUS_PROCESS(); Marshal.PtrToStructure(structPtr, status); services[i] = selector(status); } } finally { Marshal.FreeHGlobal(memory); if (databaseHandle != IntPtr.Zero) { Interop.mincore.CloseServiceHandle(databaseHandle); } } return(services); }
private unsafe void GenerateNames() { if (_machineName.Length == 0) { throw new ArgumentException(SR.NoMachineName); } IntPtr databaseHandle = IntPtr.Zero; IntPtr memory = IntPtr.Zero; int bytesNeeded; int servicesReturned; int resumeHandle = 0; try { databaseHandle = GetDataBaseHandleWithEnumerateAccess(_machineName); Interop.mincore.EnumServicesStatusEx( databaseHandle, Interop.SC_ENUM_PROCESS_INFO, Interop.SERVICE_TYPE_WIN32, Interop.STATUS_ALL, IntPtr.Zero, 0, out bytesNeeded, out servicesReturned, ref resumeHandle, null); memory = Marshal.AllocHGlobal(bytesNeeded); Interop.mincore.EnumServicesStatusEx( databaseHandle, Interop.SC_ENUM_PROCESS_INFO, Interop.SERVICE_TYPE_WIN32, Interop.STATUS_ALL, memory, bytesNeeded, out bytesNeeded, out servicesReturned, ref resumeHandle, null); // Since the service name of one service cannot be equal to the // service or display name of another service, we can safely // loop through all services checking if either the service or // display name matches the user given name. If there is a // match, then we've found the service. for (int i = 0; i < servicesReturned; i++) { IntPtr structPtr = (IntPtr)((long)memory + (i * Marshal.SizeOf <Interop.ENUM_SERVICE_STATUS_PROCESS>())); Interop.ENUM_SERVICE_STATUS_PROCESS status = new Interop.ENUM_SERVICE_STATUS_PROCESS(); Marshal.PtrToStructure(structPtr, status); if (string.Equals(_eitherName, status.serviceName, StringComparison.OrdinalIgnoreCase) || string.Equals(_eitherName, status.displayName, StringComparison.OrdinalIgnoreCase)) { if (_name == null) { _name = status.serviceName; } if (_displayName == null) { _displayName = status.displayName; } _eitherName = string.Empty; return; } } throw new InvalidOperationException(SR.Format(SR.NoService, _eitherName, _machineName)); } finally { Marshal.FreeHGlobal(memory); if (databaseHandle != IntPtr.Zero) { Interop.mincore.CloseServiceHandle(databaseHandle); } } }