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 "do nothing" action SC_ACTION action2 = new SC_ACTION(); action2.Type = SC_ACTION_TYPE.SC_ACTION_NONE; action2.Delay = delay; Marshal.StructureToPtr(action2, (IntPtr)((Int64)actionPtr + Marshal.SizeOf(typeof(SC_ACTION))), false); // Set up the failure actions SERVICE_FAILURE_ACTIONS failureActions = new SERVICE_FAILURE_ACTIONS(); failureActions.dwResetPeriod = 1 * 24 * 60 * 60; //Time after which to reset the failure count in seconds, set to 1 day 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); } } }
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 "do nothing" action SC_ACTION action2 = new SC_ACTION(); action2.Type = SC_ACTION_TYPE.SC_ACTION_NONE; action2.Delay = delay; Marshal.StructureToPtr(action2, (IntPtr)((Int64)actionPtr + Marshal.SizeOf(typeof(SC_ACTION))), false); // Set up the failure actions SERVICE_FAILURE_ACTIONS failureActions = new SERVICE_FAILURE_ACTIONS(); failureActions.dwResetPeriod = 1*24*60*60; //Time after which to reset the failure count in seconds, set to 1 day 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); } } }