/// <summary> /// Changes the failure actions of the service. /// </summary> /// <param name="failureActions">The failure actions.</param> /// <exception cref="Win32Exception"></exception> public void ChangeFailureActions(Advapi32.ServiceFailureActions failureActions) { if (QueryServiceStatus().currentState != Advapi32.ServiceCurrentState.Stopped) { throw new ServiceNotStoppedException(); } IntPtr ptr = IntPtr.Zero; //Create the unmanaged struct Advapi32.ServiceConfigFailureActions serviceConfigFailureActions; serviceConfigFailureActions.resetPeriode = failureActions.ResetPeriode; serviceConfigFailureActions.rebootMessage = failureActions.RebootMessage; serviceConfigFailureActions.command = failureActions.Command; serviceConfigFailureActions.actionsLength = (uint)failureActions.Actions.Count; serviceConfigFailureActions.actions = failureActions.Actions.ToArray(); try { // Copy the struct to unmanaged memory ptr = Marshal.AllocHGlobal(Marshal.SizeOf(serviceConfigFailureActions)); Marshal.StructureToPtr(serviceConfigFailureActions, ptr, fDeleteOld: false); //Call ChangeServiceConfig2 if (!Advapi32.ChangeServiceConfig2(this, Advapi32.ServiceInfoLevel.FailureActions, ptr)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); } } }
/// <summary> /// Changes the failure actions of the service. /// </summary> /// <param name="failureActions">The failure actions.</param> /// <exception cref="Win32Exception"></exception> public void ChangeFailureActions(Advapi32.ServiceFailureActions failureActions) { if (QueryServiceStatus().currentState != Advapi32.ServiceCurrentState.Stopped) { throw new ServiceNotStoppedException(); } int size = Marshal.SizeOf <Advapi32.ScAction>(); IntPtr ptr = failureActions.Actions != null?Marshal.AllocHGlobal(size *failureActions.Actions.Count) : IntPtr.Zero; try { if (ptr != IntPtr.Zero) { IntPtr nextAction = ptr; for (int i = 0; i < failureActions.Actions.Count; i++) { Marshal.StructureToPtr(failureActions.Actions[i], nextAction, false); nextAction = IntPtr.Add(nextAction, size); } } //Create the unmanaged struct var serviceConfigFailureActions = new Advapi32.ServiceConfigFailureActions { resetPeriode = failureActions.ResetPeriode == TimeSpan.MaxValue || failureActions.ResetPeriode == Timeout.InfiniteTimeSpan ? Kernel32.Infinite : (uint)Math.Round(failureActions.ResetPeriode.TotalSeconds), rebootMessage = failureActions.RebootMessage, command = failureActions.Command, actionsLength = (uint)(failureActions.Actions?.Count ?? 0), actions = ptr }; IntPtr ptrServiceFailureActions = Marshal.AllocHGlobal(Marshal.SizeOf <Advapi32.ServiceConfigFailureActions>()); try { //Copy struct to unmanaged memory Marshal.StructureToPtr(serviceConfigFailureActions, ptrServiceFailureActions, false); try { if (!Advapi32.ChangeServiceConfig2(this, Advapi32.ServiceInfoLevel.FailureActions, ptrServiceFailureActions)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { Marshal.DestroyStructure <Advapi32.ServiceConfigFailureActions>(ptrServiceFailureActions); } } finally { Marshal.FreeHGlobal(ptrServiceFailureActions); } } finally { if (ptr != IntPtr.Zero) { IntPtr nextAction = ptr; for (int i = 0; i < failureActions.Actions.Count; i++) { Marshal.DestroyStructure <Advapi32.ScAction>(nextAction); nextAction = IntPtr.Add(nextAction, size); } Marshal.FreeHGlobal(ptr); } } }