public void SetRecoveryOptions() { uint delay = 60000; SC_ACTION pFirstFailure = new SC_ACTION(); pFirstFailure.Type = SC_ACTION_TYPE.SC_ACTION_RESTART; pFirstFailure.Delay = delay; SC_ACTION pSecondFailure = new SC_ACTION(); pSecondFailure.Type = SC_ACTION_TYPE.SC_ACTION_RESTART; pSecondFailure.Delay = delay; SC_ACTION pSubsequentFailures = new SC_ACTION(); pSubsequentFailures.Type = SC_ACTION_TYPE.SC_ACTION_RESTART; pSubsequentFailures.Delay = delay; int pDaysToResetFailureCount = 0; int NUM_ACTIONS = 3; int[] arrActions = new int[NUM_ACTIONS * 2]; int index = 0; arrActions[index++] = (int)pFirstFailure.Type; arrActions[index++] = (int)pFirstFailure.Delay; arrActions[index++] = (int)pSecondFailure.Type; arrActions[index++] = (int)pSecondFailure.Delay; arrActions[index++] = (int)pSubsequentFailures.Type; arrActions[index++] = (int)pSubsequentFailures.Delay; IntPtr tmpBuff = Marshal.AllocHGlobal(NUM_ACTIONS * 8); try { Marshal.Copy(arrActions, 0, tmpBuff, NUM_ACTIONS * 2); SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS(); sfa.cActions = 3; sfa.dwResetPeriod = pDaysToResetFailureCount; sfa.lpCommand = null; sfa.lpRebootMsg = null; sfa.lpsaActions = new IntPtr(tmpBuff.ToInt32()); bool success = ChangeServiceFailureActions(_ServiceHandle, SERVICE_CONFIG_FAILURE_ACTIONS, ref sfa); if (!success) { if (GetLastError() == ERROR_ACCESS_DENIED) { throw new Exception("Access denied while setting failure actions."); } else { throw new Exception("Unknown error while setting failure actions."); } } } finally { Marshal.FreeHGlobal(tmpBuff); tmpBuff = IntPtr.Zero; } }
public bool HasRestartOnFailure(string serviceName) { const int bufferSize = 1024 * 8; IntPtr service = IntPtr.Zero; IntPtr bufferPtr = IntPtr.Zero; bool result = false; try { // Open the service service = OpenService(serviceName, ServiceAccessRights.SERVICE_QUERY_CONFIG); int dwBytesNeeded = 0; // Allocate memory for struct bufferPtr = Marshal.AllocHGlobal(bufferSize); int queryResult = NativeMethods.QueryServiceConfig2( service, ServiceConfig2InfoLevel.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)); // Determine whether the service is set to auto restart if (config.cActions != 0) { SC_ACTION action = (SC_ACTION)Marshal.PtrToStructure(config.lpsaActions, typeof(SC_ACTION)); result = (action.Type == SC_ACTION_TYPE.SC_ACTION_RESTART); } return(result); } finally { // Clean up if (bufferPtr != IntPtr.Zero) { Marshal.FreeHGlobal(bufferPtr); } if (service != IntPtr.Zero) { NativeMethods.CloseServiceHandle(service); } } }
public void SetRestartOnFailure(string serviceName) { const int actionCount = 2; const uint delay = 60000; IntPtr service = IntPtr.Zero; IntPtr failureActionsPtr = IntPtr.Zero; IntPtr actionPtr = IntPtr.Zero; try { // Open the service service = OpenService(serviceName, ServiceAccessRights.SERVICE_CHANGE_CONFIG | ServiceAccessRights.SERVICE_START); // Allocate memory for the individual actions actionPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SC_ACTION)) * actionCount); // Set up the restart action SC_ACTION action1 = new SC_ACTION(); action1.Type = SC_ACTION_TYPE.SC_ACTION_RESTART; action1.Delay = delay; Marshal.StructureToPtr(action1, actionPtr, false); // Set up the restart action SC_ACTION action2 = new SC_ACTION(); action2.Type = SC_ACTION_TYPE.SC_ACTION_RESTART; action2.Delay = delay; Marshal.StructureToPtr(action2, (IntPtr)((Int64)actionPtr + Marshal.SizeOf(typeof(SC_ACTION))), false); //// Set up the restart action //SC_ACTION action3 = new SC_ACTION(); //action3.Type = SC_ACTION_TYPE.SC_ACTION_RESTART; //action3.Delay = delay; //Marshal.StructureToPtr(action3, (IntPtr)((Int64)actionPtr + Marshal.SizeOf(typeof(SC_ACTION)) * 2), false); // Set up the failure actions SERVICE_FAILURE_ACTIONS failureActions = new SERVICE_FAILURE_ACTIONS(); failureActions.dwResetPeriod = 0; failureActions.cActions = actionCount; failureActions.lpsaActions = actionPtr; failureActionsPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SERVICE_FAILURE_ACTIONS))); Marshal.StructureToPtr(failureActions, failureActionsPtr, false); // Make the change int changeResult = NativeMethods.ChangeServiceConfig2( service, ServiceConfig2InfoLevel.SERVICE_CONFIG_FAILURE_ACTIONS, failureActionsPtr); // Check that the change occurred if (changeResult == 0) { throw new Win32Exception(Marshal.GetLastWin32Error(), "Unable to change the Service configuration."); } } finally { // Clean up if (failureActionsPtr != IntPtr.Zero) { Marshal.FreeHGlobal(failureActionsPtr); } if (actionPtr != IntPtr.Zero) { Marshal.FreeHGlobal(actionPtr); } if (service != IntPtr.Zero) { NativeMethods.CloseServiceHandle(service); } } }