2using System.ComponentModel;
4using System.ServiceProcess;
10 internal class ServiceHandle : SafeHandle
12 internal ServiceHandle() : base(IntPtr.Zero, ownsHandle: true)
16 protected override bool ReleaseHandle()
18 return Win32.CloseServiceHandle(this.handle);
21 public override bool IsInvalid
26 return this.handle == IntPtr.Zero;
30 public virtual void Start(
bool throwIfAlreadyRunning =
true)
32 if (!
Win32.StartServiceW(
this, 0, IntPtr.Zero))
34 int win32Error = Marshal.GetLastWin32Error();
36 if (win32Error !=
Win32.ERROR_SERVICE_ALREADY_RUNNING || throwIfAlreadyRunning)
37 throw new Win32Exception(win32Error);
41 public virtual void Delete()
43 if (!
Win32.DeleteService(
this))
44 throw new Win32Exception(Marshal.GetLastWin32Error());
47 public virtual void SetDescription(
string description)
49 ServiceDescriptionInfo descriptionInfo =
new(description ??
string.Empty);
50 IntPtr lpDescriptionInfo = Marshal.AllocHGlobal(Marshal.SizeOf<ServiceDescriptionInfo>());
53 Marshal.StructureToPtr(descriptionInfo, lpDescriptionInfo, fDeleteOld:
false);
56 if (!
Win32.ChangeServiceConfig2W(
this, ServiceConfigInfoTypeLevel.ServiceDescription, lpDescriptionInfo))
57 throw new Win32Exception(Marshal.GetLastWin32Error());
61 Marshal.DestroyStructure<ServiceDescriptionInfo>(lpDescriptionInfo);
66 Marshal.FreeHGlobal(lpDescriptionInfo);
70 public virtual void SetFailureActions(ServiceFailureActions serviceFailureActions)
72 ServiceFailureActionsInfo failureActions = serviceFailureActions is
null ? ServiceFailureActionsInfo.Default :
new ServiceFailureActionsInfo(serviceFailureActions.ResetPeriod, serviceFailureActions.RebootMessage, serviceFailureActions.RestartCommand, serviceFailureActions.Actions);
73 IntPtr lpFailureActions = Marshal.AllocHGlobal(Marshal.SizeOf<ServiceFailureActionsInfo>());
76 Marshal.StructureToPtr(failureActions, lpFailureActions, fDeleteOld:
false);
79 if (!
Win32.ChangeServiceConfig2W(
this, ServiceConfigInfoTypeLevel.FailureActions, lpFailureActions))
80 throw new Win32Exception(Marshal.GetLastWin32Error());
84 Marshal.DestroyStructure<ServiceFailureActionsInfo>(lpFailureActions);
89 Marshal.FreeHGlobal(lpFailureActions);
93 public virtual void SetFailureActionFlag(
bool enabled)
95 ServiceFailureActionsFlag failureActionsFlag =
new(enabled);
96 IntPtr lpFailureActionsFlag = Marshal.AllocHGlobal(Marshal.SizeOf<ServiceFailureActionsFlag>());
99 Marshal.StructureToPtr(failureActionsFlag, lpFailureActionsFlag, fDeleteOld:
false);
102 bool result =
Win32.ChangeServiceConfig2W(
this, ServiceConfigInfoTypeLevel.FailureActionsFlag, lpFailureActionsFlag);
104 throw new Win32Exception(Marshal.GetLastWin32Error());
108 Marshal.DestroyStructure<ServiceFailureActionsFlag>(lpFailureActionsFlag);
113 Marshal.FreeHGlobal(lpFailureActionsFlag);
117 public virtual void ChangeConfig(
string displayName,
string binaryPath, ServiceType serviceType,
ServiceStartType startupType,
ErrorSeverity errorSeverity, Win32ServiceCredentials credentials)
119 bool success =
Win32.ChangeServiceConfigW(
this, serviceType, startupType, errorSeverity, binaryPath,
null, IntPtr.Zero,
null, credentials.UserName, credentials.Password, displayName);
121 throw new Win32Exception(Marshal.GetLastWin32Error());
Handles interaction with Windows Service API.
ErrorSeverity
Error severity
ServiceStartType
How the windows service should be started.