private void FillMembers(NativeMethods.SERVICE_FAILURE_ACTIONS actions) { m_resetTime = new TimeSpan(0, 0, (int)actions.dwResetPeriod); if (actions.rebootMsg != IntPtr.Zero) { m_rebootMessage = Marshal.PtrToStringUni(actions.rebootMsg); } if (actions.command != IntPtr.Zero) { m_command = Marshal.PtrToStringUni(actions.command); } if (actions.actions != IntPtr.Zero) { NativeMethods.SC_ACTION nativeAction = new NativeMethods.SC_ACTION(); int sizeSCACTION = Marshal.SizeOf(nativeAction); //The unmanaged code is a pointer to memory so we have to enumerate the elements one by one int maxActions = Math.Max((int)actions.numActions, MaximumActions); for (int index = 0; index < maxActions; ++index) { //Calculate the address of the next element IntPtr pElement = (IntPtr)(actions.actions.ToInt64() + (sizeSCACTION * index)); //Marshal the data back nativeAction = (NativeMethods.SC_ACTION)Marshal.PtrToStructure(pElement, typeof(NativeMethods.SC_ACTION)); //Build the actual element Actions[index] = new ServiceAction(nativeAction); } ; } ; }
private void UpdateAdvancedSettings(ServiceController service) { //Set up the failure actions if (FailureActions.HasNondefaultValues()) { NativeMethods.SERVICE_FAILURE_ACTIONS sfa = new NativeMethods.SERVICE_FAILURE_ACTIONS(); try { //Build the SFA structure sfa = new NativeMethods.SERVICE_FAILURE_ACTIONS(FailureActions); //We don't want to leave the handle laying around so trap it using (SafeHandle handle = service.ServiceHandle) { //Update the configuration if (!NativeMethods.ChangeServiceConfig2(handle, NativeMethods.SERVICE_CONFIG_INFOLEVEL.FAILURE_ACTIONS, ref sfa)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } }; } finally { //Clean up sfa.Clear(); }; } ; Context.LogMessage("Updated service '" + ServiceName + "' configuration"); }
internal ServiceFailureActions(NativeMethods.SERVICE_FAILURE_ACTIONS actions) { FillMembers(actions); }