static SC_ACTION GetScAction(ServiceRecoveryAction action, uint restartServiceAfter) { var scAction = new SC_ACTION(); SC_ACTION_TYPE actionType = default(SC_ACTION_TYPE); switch (action) { case ServiceRecoveryAction.TakeNoAction: actionType = SC_ACTION_TYPE.None; break; case ServiceRecoveryAction.RestartService: actionType = SC_ACTION_TYPE.RestartService; break; case ServiceRecoveryAction.RestartComputer: actionType = SC_ACTION_TYPE.RebootComputer; break; case ServiceRecoveryAction.RunProgram: actionType = SC_ACTION_TYPE.RunCommand; break; } scAction.Type = actionType; scAction.Delay = restartServiceAfter; return(scAction); }
public void AddAction(ServiceRecoveryAction serviceRecoveryAction) { if (_actions.Count == 3) { throw new TopshelfException("Recovery action can not be added. " + "Windows recovery does not support more than 3 actions"); } _actions.Add(serviceRecoveryAction); }
public void AddAction(ServiceRecoveryAction serviceRecoveryAction) { _actions.Add(serviceRecoveryAction); }
public static void SetServiceRecoveryOptions( string serviceName, ServiceRecoveryOptions recoveryOptions) { if (recoveryOptions == null) { throw new ArgumentNullException("recoveryOptions"); } bool requiresShutdownPriveleges = recoveryOptions.FirstFailureAction == ServiceRecoveryAction.RestartComputer || recoveryOptions.SecondFailureAction == ServiceRecoveryAction.RestartComputer || recoveryOptions.SubsequentFailureAction == ServiceRecoveryAction.RestartComputer; if (requiresShutdownPriveleges) { GrantShutdownPrivileges(); } int actionCount = 3; var restartServiceAfter = (uint)TimeSpan.FromMinutes( recoveryOptions.RestartServiceWaitMinutes).TotalMilliseconds; IntPtr failureActionsPointer = IntPtr.Zero; IntPtr actionPointer = IntPtr.Zero; ServiceController controller = null; try { // Open the service controller = new ServiceController(serviceName); // Set up the failure actions var failureActions = new SERVICE_FAILURE_ACTIONS(); failureActions.dwResetPeriod = (int)TimeSpan.FromDays(recoveryOptions.ResetFailureCountWaitDays).TotalSeconds; failureActions.cActions = (uint)actionCount; failureActions.lpRebootMsg = recoveryOptions.RestartSystemMessage; // allocate memory for the individual actions actionPointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SC_ACTION)) * actionCount); ServiceRecoveryAction[] actions = { recoveryOptions.FirstFailureAction, recoveryOptions.SecondFailureAction, recoveryOptions.SubsequentFailureAction }; for (int i = 0; i < actions.Length; i++) { ServiceRecoveryAction action = actions[i]; SC_ACTION scAction = GetScAction(action, restartServiceAfter); Marshal.StructureToPtr(scAction, (IntPtr)((Int64)actionPointer + (Marshal.SizeOf(typeof(SC_ACTION))) * i), false); } failureActions.lpsaActions = actionPointer; string command = recoveryOptions.RunProgramCommand; if (command != null) { failureActions.lpCommand = command; } failureActionsPointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SERVICE_FAILURE_ACTIONS))); Marshal.StructureToPtr(failureActions, failureActionsPointer, false); // Make the change bool success = ChangeServiceConfig2(controller.ServiceHandle.DangerousGetHandle(), SERVICE_CONFIG_FAILURE_ACTIONS, failureActionsPointer); // Check that the change occurred if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Unable to change the Service configuration."); } } finally { if (failureActionsPointer != IntPtr.Zero) { Marshal.FreeHGlobal(failureActionsPointer); } if (actionPointer != IntPtr.Zero) { Marshal.FreeHGlobal(actionPointer); } if (controller != null) { controller.Dispose(); } //log.Debug(m => m("Done setting service recovery options.")); } }
static SC_ACTION GetScAction(ServiceRecoveryAction action, uint restartServiceAfter) { var scAction = new SC_ACTION(); SC_ACTION_TYPE actionType = default(SC_ACTION_TYPE); switch (action) { case ServiceRecoveryAction.TakeNoAction: actionType = SC_ACTION_TYPE.None; break; case ServiceRecoveryAction.RestartService: actionType = SC_ACTION_TYPE.RestartService; break; case ServiceRecoveryAction.RestartComputer: actionType = SC_ACTION_TYPE.RebootComputer; break; case ServiceRecoveryAction.RunProgram: actionType = SC_ACTION_TYPE.RunCommand; break; } scAction.Type = actionType; scAction.Delay = restartServiceAfter; return scAction; }