/// <summary> /// Changes the service failure action information /// </summary> /// <param name="serviceName">The service to look for</param> /// <param name="resetPeriodInDays">The reset period (in days)</param> /// <param name="rebootMessage">The message displayed on reboot</param> /// <param name="commandLine">Program command line</param> /// <param name="actions">Ordered list of actions to add to the service configuration</param> public static void SetServiceInformation(string serviceName, int resetPeriodInDays, string rebootMessage, string commandLine, ServiceFailureActionType[] actions) { // Get a valid service handle IntPtr serviceHandle = LookupServiceHandle(serviceName, scope.Modify); // marshal the actions ServiceFailureAction action = new ServiceFailureAction(); IntPtr lpsaActions = Marshal.AllocHGlobal(Marshal.SizeOf(action) * actions.Length); // Marshal.StructureToPtr(action, lpsaActions, false); IntPtr nextAction = lpsaActions; for (int i = 0; i < actions.Length; i++) { action = new ServiceFailureAction(); action.Type = actions[i]; action.Delay = (UInt32)TimeSpan.FromMinutes(1).TotalMilliseconds; Marshal.StructureToPtr(action, nextAction, false); nextAction = (IntPtr)(nextAction.ToInt64() + Marshal.SizeOf(action)); } // now put it all in one struct SERVICE_FAILURE_ACTIONS failureActions = new SERVICE_FAILURE_ACTIONS(); failureActions.dwResetPeriod = (int)TimeSpan.FromDays(resetPeriodInDays).TotalSeconds; failureActions.lpRebootMsg = rebootMessage; failureActions.lpCommand = commandLine; failureActions.cActions = actions.Length; failureActions.lpsaActions = lpsaActions; IntPtr lpInfo = Marshal.AllocHGlobal(Marshal.SizeOf(failureActions)); Marshal.StructureToPtr(failureActions, lpInfo, true); // do the change bool success = ChangeServiceConfig2(serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS, lpInfo); //int errorcode = GetLatError(); // clean up Marshal.FreeHGlobal(lpInfo); Marshal.FreeHGlobal(lpsaActions); if (serviceHandle != IntPtr.Zero) { CloseServiceHandle(serviceHandle); } if (false == success) { throw new System.Runtime.InteropServices.ExternalException(string.Format("Cannot set ServiceConfig. Last Error: {0}.", Marshal.GetLastWin32Error())); } }
/// <summary> /// Look up the Failure action information for a service /// </summary> /// <param name="serviceName">The service to look up</param> /// <returns>Service Failure Action information</returns> public static ServiceInformation GetSericeInformation(string serviceName) { UInt32 dwBytesNeeded; // Get a valid service handle IntPtr serviceHandle = LookupServiceHandle(serviceName, scope.Query); // Determine the buffer size needed bool sucess = QueryServiceConfig2(serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS, IntPtr.Zero, 0, out dwBytesNeeded); IntPtr ptr = Marshal.AllocHGlobal((int)dwBytesNeeded); sucess = QueryServiceConfig2(serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS, ptr, dwBytesNeeded, out dwBytesNeeded); if (false == sucess) { throw new System.Runtime.InteropServices.ExternalException(string.Format("Cannot find SERVICE_FAILURE_ACTIONS struct. Last Error: {0}.", Marshal.GetLastWin32Error())); } SERVICE_FAILURE_ACTIONS failureActions = new SERVICE_FAILURE_ACTIONS(); Marshal.PtrToStructure(ptr, failureActions); ServiceInformation serviceConfigInformation = new ServiceInformation((UInt32)failureActions.dwResetPeriod, failureActions.lpRebootMsg, failureActions.lpCommand, failureActions.cActions); int offset = 0; for (int i = 0; i < failureActions.cActions; i++) { ServiceFailureAction action = new ServiceFailureAction(); action.Type = (ServiceFailureActionType)Marshal.ReadInt32(failureActions.lpsaActions, offset); offset += sizeof(Int32); action.Delay = (UInt32)Marshal.ReadInt32(failureActions.lpsaActions, offset); offset += sizeof(Int32); serviceConfigInformation.Actions[i] = action; } // clean up Marshal.FreeHGlobal(ptr); if (serviceHandle != IntPtr.Zero) { CloseServiceHandle(serviceHandle); } return(serviceConfigInformation); }
/// <summary> /// Changes the service failure action information /// </summary> /// <param name="serviceName">The service to look for</param> /// <param name="resetPeriodInDays">The reset period (in days)</param> /// <param name="rebootMessage">The message displayed on reboot</param> /// <param name="commandLine">Program command line</param> /// <param name="actions">Ordered list of actions to add to the service configuration</param> public static void SetServiceInformation(string serviceName, int resetPeriodInDays, string rebootMessage, string commandLine, ServiceFailureActionType[] actions) { // Get a valid service handle IntPtr serviceHandle = LookupServiceHandle(serviceName, scope.Modify); // marshal the actions ServiceFailureAction action = new ServiceFailureAction(); IntPtr lpsaActions = Marshal.AllocHGlobal(Marshal.SizeOf(action) * actions.Length); // Marshal.StructureToPtr(action, lpsaActions, false); IntPtr nextAction = lpsaActions; for (int i = 0; i < actions.Length; i++) { action = new ServiceFailureAction(); action.Type = actions[i]; action.Delay = (UInt32)TimeSpan.FromMinutes(1).TotalMilliseconds; Marshal.StructureToPtr(action, nextAction, false); nextAction = (IntPtr)(nextAction.ToInt64() + Marshal.SizeOf(action)); } // now put it all in one struct SERVICE_FAILURE_ACTIONS failureActions = new SERVICE_FAILURE_ACTIONS(); failureActions.dwResetPeriod = (int)TimeSpan.FromDays(resetPeriodInDays).TotalSeconds; failureActions.lpRebootMsg = rebootMessage; failureActions.lpCommand = commandLine; failureActions.cActions = actions.Length; failureActions.lpsaActions = lpsaActions; IntPtr lpInfo = Marshal.AllocHGlobal(Marshal.SizeOf(failureActions)); Marshal.StructureToPtr(failureActions, lpInfo, true); // do the change bool success = ChangeServiceConfig2(serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS, lpInfo); //int errorcode = GetLatError(); // clean up Marshal.FreeHGlobal(lpInfo); Marshal.FreeHGlobal(lpsaActions); if (serviceHandle != IntPtr.Zero) { CloseServiceHandle(serviceHandle); } if (false == success) { throw new System.Runtime.InteropServices.ExternalException(string.Format("Cannot set ServiceConfig. Last Error: {0}.", Marshal.GetLastWin32Error())); } }
/// <summary> /// Look up the Failure action information for a service /// </summary> /// <param name="serviceName">The service to look up</param> /// <returns>Service Failure Action information</returns> public static ServiceInformation GetSericeInformation(string serviceName) { UInt32 dwBytesNeeded; // Get a valid service handle IntPtr serviceHandle = LookupServiceHandle(serviceName, scope.Query); // Determine the buffer size needed bool sucess = QueryServiceConfig2(serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS, IntPtr.Zero, 0, out dwBytesNeeded); IntPtr ptr = Marshal.AllocHGlobal((int)dwBytesNeeded); sucess = QueryServiceConfig2(serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS, ptr, dwBytesNeeded, out dwBytesNeeded); if (false == sucess) { throw new System.Runtime.InteropServices.ExternalException(string.Format("Cannot find SERVICE_FAILURE_ACTIONS struct. Last Error: {0}.", Marshal.GetLastWin32Error())); } SERVICE_FAILURE_ACTIONS failureActions = new SERVICE_FAILURE_ACTIONS(); Marshal.PtrToStructure(ptr, failureActions); ServiceInformation serviceConfigInformation = new ServiceInformation((UInt32)failureActions.dwResetPeriod, failureActions.lpRebootMsg, failureActions.lpCommand, failureActions.cActions); int offset = 0; for (int i = 0; i < failureActions.cActions; i++) { ServiceFailureAction action = new ServiceFailureAction(); action.Type = (ServiceFailureActionType)Marshal.ReadInt32(failureActions.lpsaActions, offset); offset += sizeof(Int32); action.Delay = (UInt32)Marshal.ReadInt32(failureActions.lpsaActions, offset); offset += sizeof(Int32); serviceConfigInformation.Actions[i] = action; } // clean up Marshal.FreeHGlobal(ptr); if (serviceHandle != IntPtr.Zero) { CloseServiceHandle(serviceHandle); } return serviceConfigInformation; }