diff --git a/src/Core/ServiceWrapper/Main.cs b/src/Core/ServiceWrapper/Main.cs index 4bcf9af..19e1351 100644 --- a/src/Core/ServiceWrapper/Main.cs +++ b/src/Core/ServiceWrapper/Main.cs @@ -17,7 +17,6 @@ using log4net.Appender; using log4net.Config; using log4net.Core; using log4net.Layout; -using Microsoft.Win32; using winsw.Extensions; using winsw.Logging; using winsw.Native; @@ -643,47 +642,30 @@ namespace winsw password, descriptor.ServiceDependencies); - // update the description - /* Somehow this doesn't work, even though it doesn't report an error - Win32Service s = svc.Select(d.Id); - s.Description = d.Description; - s.Commit(); - */ + using ServiceManager scm = new ServiceManager(); + using Service sc = scm.Open(descriptor.Id); - // so using a classic method to set the description. Ugly. - Registry.LocalMachine - .OpenSubKey("System") - .OpenSubKey("CurrentControlSet") - .OpenSubKey("Services") - .OpenSubKey(descriptor.Id, true) - .SetValue("Description", descriptor.Description); + sc.SetDescription(descriptor.Description); var actions = descriptor.FailureActions; - var isDelayedAutoStart = descriptor.StartMode == StartMode.Automatic && descriptor.DelayedAutoStart; - if (actions.Count > 0 || isDelayedAutoStart) + if (actions.Count > 0) { - using ServiceManager scm = new ServiceManager(); - using Service sc = scm.Open(descriptor.Id); + sc.SetFailureActions(descriptor.ResetFailureAfter, actions); + } - // Delayed auto start - if (isDelayedAutoStart) - { - sc.SetDelayedAutoStart(true); - } - - // Set the failure actions - if (actions.Count > 0) - { - sc.ChangeConfig(descriptor.ResetFailureAfter, actions); - } + var isDelayedAutoStart = descriptor.StartMode == StartMode.Automatic && descriptor.DelayedAutoStart; + if (isDelayedAutoStart) + { + sc.SetDelayedAutoStart(true); } if (descriptor.SecurityDescriptor != null) { + // throws ArgumentException RawSecurityDescriptor rawSecurityDescriptor = new RawSecurityDescriptor(descriptor.SecurityDescriptor); byte[] securityDescriptorBytes = new byte[rawSecurityDescriptor.BinaryLength]; rawSecurityDescriptor.GetBinaryForm(securityDescriptorBytes, 0); - Advapi32.SetServiceObjectSecurity(/*TODO*/default, SecurityInfos.DiscretionaryAcl, securityDescriptorBytes); + _ = Advapi32.SetServiceObjectSecurity(sc.Handle, SecurityInfos.DiscretionaryAcl, securityDescriptorBytes); } return; diff --git a/src/Core/WinSWCore/Native/Advapi32.cs b/src/Core/WinSWCore/Native/Advapi32.cs index df0bb69..6604f33 100755 --- a/src/Core/WinSWCore/Native/Advapi32.cs +++ b/src/Core/WinSWCore/Native/Advapi32.cs @@ -41,16 +41,16 @@ namespace winsw.Native } } - public class Service : IDisposable + public struct Service : IDisposable { - internal IntPtr Handle; + public IntPtr Handle; internal Service(IntPtr service) { Handle = service; } - public void ChangeConfig(TimeSpan failureResetPeriod, List actions) + public void SetFailureActions(TimeSpan failureResetPeriod, List actions) { SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS { @@ -101,6 +101,11 @@ namespace winsw.Native } } + public void SetDescription(string description) + { + _ = Advapi32.ChangeServiceConfig2(Handle, SERVICE_CONFIG_INFOLEVEL.SERVICE_CONFIG_DESCRIPTION, new SERVICE_DESCRIPTION { lpDescription = description }); + } + public void Dispose() { if (Handle != IntPtr.Zero) @@ -267,6 +272,9 @@ namespace winsw.Native [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "ChangeServiceConfig2W")] internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, in SERVICE_DELAYED_AUTO_START lpInfo); + [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "ChangeServiceConfig2W")] + internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, in SERVICE_DESCRIPTION lpInfo); + [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "OpenSCManagerW")] internal static extern IntPtr OpenSCManager(string? lpMachineName, string? lpDatabaseName, uint dwDesiredAccess); @@ -589,4 +597,10 @@ namespace winsw.Native { public bool fDelayedAutostart; } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct SERVICE_DESCRIPTION + { + public string lpDescription; + } }