public static ServiceRecoveryOptions FromConfiguration(RecoveryOptionsElement recoveryOptionsElement) { var recoveryOptions = new ServiceRecoveryOptions { FirstFailureAction = recoveryOptionsElement.FirstFailureAction, SecondFailureAction = recoveryOptionsElement.SecondFailureAction, SubsequentFailureActions = recoveryOptionsElement.SubsequentFailureActions, DaysToResetFailAcount = recoveryOptionsElement.DaysToResetFailAcount, CommandToLaunchOnFailure = recoveryOptionsElement.CommandToLaunchOnFailure, MinutesToRestartService = recoveryOptionsElement.MinutesToRestartService, RebootMessage = recoveryOptionsElement.RebootMessage }; recoveryOptions.Validate(); return recoveryOptions; }
public bool Equals(ServiceRecoveryOptions other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return Equals(other.FirstFailureAction, FirstFailureAction) && Equals(other.SecondFailureAction, SecondFailureAction) && Equals(other.SubsequentFailureActions, SubsequentFailureActions) && other.DaysToResetFailAcount == DaysToResetFailAcount && other.MinutesToRestartService == MinutesToRestartService && Equals(other.RebootMessage, RebootMessage) && Equals(other.CommandToLaunchOnFailure, CommandToLaunchOnFailure); }
public static void SetServiceRecoveryOptions( string serviceName, ServiceRecoveryOptions recoveryOptions) { Exceptions.ThrowHelper.ThrowArgumentNullIfNull(serviceName, "serviceName"); Exceptions.ThrowHelper.ThrowArgumentOutOfRangeIfEmpty(serviceName, "serviceName"); Log.Debug("Setting service recovery options..."); bool requiresShutdownPriveleges = recoveryOptions.FirstFailureAction == ServiceRecoveryAction.RestartTheComputer || recoveryOptions.SecondFailureAction == ServiceRecoveryAction.RestartTheComputer || recoveryOptions.SubsequentFailureActions == ServiceRecoveryAction.RestartTheComputer; if (requiresShutdownPriveleges) { GrantShutdownPrivileges(); } const int actionCount = 3; var restartServiceAfter = (uint)TimeSpan.FromMinutes( recoveryOptions.MinutesToRestartService).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 { dwResetPeriod = (int)TimeSpan.FromDays(recoveryOptions.DaysToResetFailAcount).TotalSeconds, cActions = actionCount, lpRebootMsg = recoveryOptions.RebootMessage }; // allocate memory for the individual actions actionPointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SC_ACTION)) * actionCount); ServiceRecoveryAction[] actions = { recoveryOptions.FirstFailureAction, recoveryOptions.SecondFailureAction, recoveryOptions.SubsequentFailureActions }; for (int i = 0; i < actions.Length; i++) { ServiceRecoveryAction action = actions[i]; var scAction = GetScAction(action, restartServiceAfter); Marshal.StructureToPtr(scAction, (IntPtr)((Int64)actionPointer + (Marshal.SizeOf(typeof(SC_ACTION))) * i), false); } failureActions.lpsaActions = actionPointer; string command = recoveryOptions.CommandToLaunchOnFailure; 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.Close(); } Log.Debug("Done setting service recovery options."); } }
public static ServiceRecoveryOptions GetServiceRecoveryOptions(string serviceName) { Exceptions.ThrowHelper.ThrowArgumentNullIfNull(serviceName, "serviceName"); Exceptions.ThrowHelper.ThrowArgumentOutOfRangeIfEmpty(serviceName, "serviceName"); Log.Debug("Getting service recovery options..."); // 8KB is the largest buffer supported by QueryServiceConfig2 const int bufferSize = 1024 * 8; IntPtr bufferPtr = IntPtr.Zero; ServiceRecoveryOptions recoveryOptions; ServiceController controller = null; try { // Open the service controller = new ServiceController(serviceName); uint dwBytesNeeded; // Allocate memory for struct bufferPtr = Marshal.AllocHGlobal(bufferSize); int queryResult = QueryServiceConfig2( controller.ServiceHandle.DangerousGetHandle(), SERVICE_CONFIG_FAILURE_ACTIONS, bufferPtr, bufferSize, out dwBytesNeeded); if (queryResult == 0) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Unable to query the Service configuration."); } // Cast the buffer to a QUERY_SERVICE_CONFIG struct SERVICE_FAILURE_ACTIONS config = (SERVICE_FAILURE_ACTIONS)Marshal.PtrToStructure(bufferPtr, typeof(SERVICE_FAILURE_ACTIONS)); recoveryOptions = new ServiceRecoveryOptions { DaysToResetFailAcount = (int) TimeSpan.FromSeconds(config.dwResetPeriod).TotalDays, RebootMessage = config.lpRebootMsg, CommandToLaunchOnFailure = config.lpCommand }; int actionCount = config.cActions; if (actionCount != 0) { uint millisecondsToRestartService = 0; SC_ACTION[] actions = new SC_ACTION[actionCount]; for (int i = 0; i < config.cActions; i++) { SC_ACTION action = (SC_ACTION)Marshal.PtrToStructure( (IntPtr)(config.lpsaActions.ToInt32() + (Marshal.SizeOf(typeof(SC_ACTION)) * i)), typeof(SC_ACTION)); actions[i] = action; millisecondsToRestartService = action.Delay; } recoveryOptions.FirstFailureAction = GetServiceRecoveryAction(actions[0]); recoveryOptions.SecondFailureAction = GetServiceRecoveryAction(actions[1]); recoveryOptions.SubsequentFailureActions = GetServiceRecoveryAction(actions[2]); recoveryOptions.MinutesToRestartService = (int)TimeSpan.FromMilliseconds(millisecondsToRestartService).TotalMinutes; } } finally { // Clean up if (bufferPtr != IntPtr.Zero) { Marshal.FreeHGlobal(bufferPtr); } if (controller != null) { controller.Close(); } Log.Debug("Done getting service recovery options."); } return recoveryOptions; }
public CandidateWindowsServiceInfo() { StartMode = StartMode.Manual; _servicesDependedOn = new List<string>(); RecoveryOptions = new ServiceRecoveryOptions(); }