public static NativeMethods.ServiceStatusInfo ReadServiceStatus(SafeServiceHandle serviceHandle) { NativeMethods.ServiceStatusInfo ServiceStatus = default; if (!NativeMethods.QueryServiceStatus(serviceHandle, ref ServiceStatus)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(ServiceStatus); }
public static extern bool ChangeServiceConfig( SafeServiceHandle hService, uint dwServiceType, uint dwStartType, uint dwErrorControl, string?lpBinaryPathName, string?lpLoadOrderGroup, IntPtr lpdwTagId, string?lpDependencies, string?lpServiceStartName, IntPtr lpPassword, string?lpDisplayName);
/// <summary> /// Starts a service. /// </summary> /// <param name="arguments">An array of arguments to pass to the service when it starts.</param> public void Start(string?[]?arguments) { arguments ??= Array.Empty <string>(); using SafeServiceHandle ServiceManager = ServiceHelper.OpenServiceManager( MachineName, NativeMethods.SC_MANAGER_CONNECT); using SafeServiceHandle ServiceHandle = ServiceHelper.OpenService( ServiceManager, ServiceName, NativeMethods.SERVICE_START); IntPtr[] ArumentPointers = new IntPtr[arguments.Length]; int ArgumentIndex = 0; try { for (ArgumentIndex = 0; ArgumentIndex < arguments.Length; ArgumentIndex++) { if (arguments[ArgumentIndex] == null) { throw new ArgumentException($"Argument at index {ArgumentIndex} is null which cannot be passed to sevice.", nameof(arguments)); } ArumentPointers[ArgumentIndex] = Marshal.StringToHGlobalUni(arguments[ArgumentIndex]); } GCHandle gcHandle = GCHandle.Alloc(ArumentPointers, GCHandleType.Pinned); try { if (!NativeMethods.StartService(ServiceHandle, (uint)arguments.Length, gcHandle.AddrOfPinnedObject())) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { if (gcHandle.IsAllocated) { gcHandle.Free(); } } } finally { for (int i = 0; i < ArgumentIndex; i++) { Marshal.FreeHGlobal(ArumentPointers[i]); } } }
public static extern SafeServiceHandle CreateService( SafeServiceHandle hSCManager, string lpServiceName, string lpDisplayName, uint dwDesiredAccess, uint dwServiceType, uint dwStartType, uint dwErrorControl, string lpBinaryPathName, string?lpLoadOrderGroup, IntPtr lpdwTagId, string?lpDependencies, string?lpServiceStartName, IntPtr lpPassword);
/// <summary> /// Deletes a service. /// </summary> public void Delete() { using SafeServiceHandle ServiceManager = ServiceHelper.OpenServiceManager( MachineName, NativeMethods.SC_MANAGER_CONNECT); using SafeServiceHandle ServiceHandle = ServiceHelper.OpenService( ServiceManager, ServiceName, NativeMethods.DELETE); if (!NativeMethods.DeleteService(ServiceHandle)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } }
public static IEnumerable <Service> FindServices(string machineName) { using SafeServiceHandle ServiceManager = OpenServiceManager(machineName, NativeMethods.SC_MANAGER_ENUMERATE_SERVICE); uint ResumeHandle = 0; NativeMethods.EnumServicesStatus(ServiceManager, NativeMethods.SERVICE_WIN32, NativeMethods.SERVICE_STATE_ALL, IntPtr.Zero, 0, out uint BytesNeeded, out uint ServicesReturned, ref ResumeHandle); int ErrorCode = Marshal.GetLastWin32Error(); if (ErrorCode != NativeMethods.ERROR_MORE_DATA) { throw new Win32Exception(ErrorCode); } IntPtr ptr = Marshal.AllocHGlobal((int)BytesNeeded); try { if (!NativeMethods.EnumServicesStatus(ServiceManager, NativeMethods.SERVICE_WIN32, NativeMethods.SERVICE_STATE_ALL, ptr, BytesNeeded, out BytesNeeded, out ServicesReturned, ref ResumeHandle)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } Collection <Service> Status = new Collection <Service>(); for (int index = 0; index < ServicesReturned; ++index) { IntPtr itemPtr = (IntPtr)((long)ptr + (index * NativeMethods.EnumServiceStatusInfo.SizeOf)); NativeMethods.EnumServiceStatusInfo EnumServiceStatus = new NativeMethods.EnumServiceStatusInfo(); Marshal.PtrToStructure(itemPtr, EnumServiceStatus); Status.Add(new Service( machineName, EnumServiceStatus.lpServiceName ?? string.Empty, EnumServiceStatus.lpDisplayName ?? string.Empty, EnumServiceStatus.ServiceStatus.dwCurrentState)); } return(Status); } finally { Marshal.FreeHGlobal(ptr); } }
private void ControlService(uint dwAccess, uint dwControl) { using SafeServiceHandle ServiceManager = ServiceHelper.OpenServiceManager( MachineName, NativeMethods.SC_MANAGER_CONNECT); using SafeServiceHandle ServiceHandle = ServiceHelper.OpenService( ServiceManager, ServiceName, dwAccess); NativeMethods.ServiceStatusInfo Status = default; if (!NativeMethods.ControlService(ServiceHandle, dwControl, ref Status)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } State = Status.dwCurrentState; }
public static extern SafeServiceHandle OpenService( SafeServiceHandle hSCManager, string lpServiceName, uint dwDesiredAccess);
public static extern bool QueryServiceStatus(SafeServiceHandle hService, ref ServiceStatusInfo lpServiceStatus);
private static NativeMethods.ServiceConfigurationInfo ReadServiceConfiguration(SafeServiceHandle serviceHandle) { NativeMethods.QueryServiceConfig(serviceHandle, IntPtr.Zero, 0, out uint BytesNeeded); int ErrorCode = Marshal.GetLastWin32Error(); if (ErrorCode != NativeMethods.ERROR_INSUFFICIENT_BUFFER) { throw new Win32Exception(ErrorCode); } IntPtr ptr = Marshal.AllocHGlobal((int)BytesNeeded); try { if (!NativeMethods.QueryServiceConfig(serviceHandle, ptr, BytesNeeded, out BytesNeeded)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } NativeMethods.ServiceConfigurationInfo ServiceConfiguration = new NativeMethods.ServiceConfigurationInfo(); Marshal.PtrToStructure(ptr, ServiceConfiguration); return(ServiceConfiguration); } finally { Marshal.FreeHGlobal(ptr); } }
public static extern bool QueryServiceConfig(SafeServiceHandle hService, IntPtr lpServiceConfig, uint cbBufSize, out uint pcbBytesNeeded);
public static extern bool QueryServiceConfig2(SafeServiceHandle hService, uint dwInfoLevel, IntPtr lpBuffer, uint cbBufSize, out uint pcbBytesNeeded);
public static extern bool ControlService( SafeServiceHandle hService, uint dwControl, ref ServiceStatusInfo lpServiceStatus);
public static extern bool StartService(SafeServiceHandle hService, uint dwNumServiceArgs, IntPtr lpServiceArgVectors);
public static (ServiceConfiguration ServiceConfiguration, string BinaryPath) ReadServiceConfiguration(SafeServiceHandle serviceHandle, string serviceName) { NativeMethods.ServiceConfigurationInfo ServiceConfiguration = ReadServiceConfiguration(serviceHandle); (ServiceAccount Account, string?Username) = ServiceController.ConvertWindowsUsernameToServiceConfiguration(ServiceConfiguration.lpServiceStartName); ServiceStartMode StartMode = ReadServiceDelayedAutoStartConfiguration(serviceHandle) ? ServiceStartMode.AutomaticDelayedStart : (ServiceStartMode)ServiceConfiguration.dwStartType; return( new ServiceConfiguration { ServiceName = serviceName, DisplayName = ServiceConfiguration.lpDisplayName, Description = ReadServiceDescription(serviceHandle), StartMode = StartMode, Account = Account, Username = Username }, ServiceConfiguration.lpBinaryPathName ?? string.Empty); }
/// <summary> /// Configure a service. /// </summary> /// <param name="displayName"><see cref="ServiceConfiguration.DisplayName"/>.</param> /// <param name="description"><see cref="ServiceConfiguration.Description"/>.</param> /// <param name="startMode"><see cref="ServiceConfiguration.StartMode"/>.</param> /// <param name="account"><see cref="ServiceConfiguration.Account"/>.</param> /// <param name="username"><see cref="ServiceConfiguration.Username"/>.</param> /// <param name="password"><see cref="ServiceConfiguration.Password"/>.</param> /// <param name="binaryPathAndArguments">The fully qualified path to the service binary file optionally including arguments to be passed when starting the service. Specify null to leave the current value unchanged.</param> public void Configure( string?displayName, string?description, ServiceStartMode startMode, ServiceAccount account, string?username, SecureString?password, string?binaryPathAndArguments = null) { string DisplayName = string.IsNullOrEmpty(displayName) ? ServiceName : displayName; using SafeServiceHandle ServiceManager = ServiceHelper.OpenServiceManager( MachineName, NativeMethods.SC_MANAGER_CONNECT); using SafeServiceHandle ServiceHandle = ServiceHelper.OpenService( ServiceManager, ServiceName, NativeMethods.SERVICE_CHANGE_CONFIG); string?ConvertedUsername = ServiceController.ConvertServiceConfigurationToWindowsUsername( account, username); IntPtr PasswordPointer = password != null ? Marshal.SecureStringToGlobalAllocUnicode(password) : IntPtr.Zero; try { if (!NativeMethods.ChangeServiceConfig( ServiceHandle, dwServiceType: NativeMethods.SERVICE_NO_CHANGE, (uint)(startMode == ServiceStartMode.AutomaticDelayedStart ? ServiceStartMode.Automatic : startMode), dwErrorControl: NativeMethods.SERVICE_NO_CHANGE, binaryPathAndArguments, lpLoadOrderGroup: null, lpdwTagId: IntPtr.Zero, lpDependencies: null, ConvertedUsername, PasswordPointer, DisplayName)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { if (PasswordPointer != IntPtr.Zero) { Marshal.ZeroFreeGlobalAllocUnicode(PasswordPointer); } } this.DisplayName = DisplayName; ServiceHelper.ChangeServiceDescription(ServiceHandle, description); ServiceHelper.ChangeServiceDelayedAutoStartConfiguration(ServiceHandle, startMode == ServiceStartMode.AutomaticDelayedStart); lock (_SyncObject) { _FullConfigurationLoaded = false; } }
private void RefreshStatus(SafeServiceHandle serviceHandle) { NativeMethods.ServiceStatusInfo Status = ServiceHelper.ReadServiceStatus(serviceHandle); State = Status.dwCurrentState; }
public static extern bool ChangeServiceConfig2( SafeServiceHandle hService, uint dwInfoLevel, IntPtr lpInfo);
public static extern bool DeleteService(SafeServiceHandle hService);