Intereting Posts
Соглашение об именах для словаря C # Внезабойное развертывание через VS 2015 RC Фоновый работник: убедитесь, что метод ProgressChanged завершен до выполнения RunWorkerCompleted Форма с закругленными границами в C #? Кажется, не удается получить проекты библиотеки classов для сборки после обновления aspnet 5 с бета4 до бета5 Проверка возвращаемого значения функции в возвращаемой строке метода в Visual Studio Упаковка IDispatch Invoke с параметрами в C # (с DISPPARAMS) IDictionary контравариантность? Связанный с данными WPF ComboBox с вариантами, определенными в XAML? Как настроить DataGridView ComboBoxColumn с другим источником данных в каждой ячейке? C #: мониторинг скопированных или перемещенных файлов с помощью FileSystemWatcher Создать список методов classа с типами методов Требуется ли каждому определяемому пользователю classу IDisposable интерфейс для сбора мусора Различное поведение async / ждут почти теми же методами Различные комбинации массива (C #)

Настройка параметров восстановления в службах Windows

Недавно я написал небольшой class, чтобы помочь мне изменить параметры восстановления на службе Windows (большая часть кода, который я нашел где-то в Интернете). Код создает FailureAction для первого, второго и последующих сбоев. Каждый объект Failure содержит тип (None, Restart, Reboot, RunCommand) и Delay (int) в миллисекундах. Эти объекты упакованы внутри структуры и передаются в ChangeServiceConfig2 (WinAPI P / Invoke). Однако, когда я нажимаю правой кнопкой мыши на службе на консоли и перехожу на вкладку «Восстановление», вы можете установить только задержку («Перезапустить сервер после») один раз для всех сбоев (первый, второй и последующий). Когда я устанавливаю это программно, он берет задержку с первого FailureAction и игнорирует все остальные. Кто-нибудь знает, почему это так? Почему мы должны передавать значение задержки для всех объектов FailureAction, когда используется только первый? Я что-то не понимаю?

Кроме того, установка dwResetPeriod / «Сброс счетчика ошибок после» не оказывает никакого влияния.

Код:

public class ServiceConfigurator { private const int SERVICE_ALL_ACCESS = 0xF01FF; private const int SC_MANAGER_ALL_ACCESS = 0xF003F; private const int SERVICE_CONFIG_DESCRIPTION = 0x1; private const int SERVICE_CONFIG_FAILURE_ACTIONS = 0x2; private const int SERVICE_NO_CHANGE = -1; private const int ERROR_ACCESS_DENIED = 5; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private struct SERVICE_FAILURE_ACTIONS { public int dwResetPeriod; [MarshalAs(UnmanagedType.LPWStr)] public string lpRebootMsg; [MarshalAs(UnmanagedType.LPWStr)] public string lpCommand; public int cActions; public IntPtr lpsaActions; } [DllImport("advapi32.dll", EntryPoint = "ChangeServiceConfig2")] private static extern bool ChangeServiceFailureActions(IntPtr hService, int dwInfoLevel, [MarshalAs(UnmanagedType.Struct)] ref SERVICE_FAILURE_ACTIONS lpInfo); [DllImport("advapi32.dll", EntryPoint = "ChangeServiceConfig2")] private static extern bool ChangeServiceDescription(IntPtr hService, int dwInfoLevel, [MarshalAs(UnmanagedType.Struct)] ref SERVICE_DESCRIPTION lpInfo); [DllImport("kernel32.dll")] private static extern int GetLastError(); private IntPtr _ServiceHandle; public IntPtr ServiceHandle { get { return _ServiceHandle; } } public ServiceConfigurator(ServiceController svcController) { this._ServiceHandle = svcController.ServiceHandle.DangerousGetHandle(); } public void SetRecoveryOptions(FailureAction pFirstFailure, FailureAction pSecondFailure, FailureAction pSubsequentFailures, int pDaysToResetFailureCount = 0) { int NUM_ACTIONS = 3; int[] arrActions = new int[NUM_ACTIONS * 2]; int index = 0; arrActions[index++] = (int)pFirstFailure.Type; arrActions[index++] = pFirstFailure.Delay; arrActions[index++] = (int)pSecondFailure.Type; arrActions[index++] = pSecondFailure.Delay; arrActions[index++] = (int)pSubsequentFailures.Type; arrActions[index++] = 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; } } } 

Тревор

Я обнаружил, что все вкусы win 7 не имеют возможности перезапуска некоторых сервисов, даже если их перезапуск при сбое установлен на «да».

Я закончил тем, что написал сервис, чтобы отслеживать статус старта и остановки, а также (исходя из эвристики) отзывчивость (например, висит не висела). Вы хотите, чтобы этот код услуг размещался здесь?

Изменить: добавлен код

Итак, следующий код службы, на который я ссылался. Имей в виду:

  • Этот код предназначен для указания на «C: \ appMon» для ведения журнала и использования процессора. пороговые значения.
  • Этот код уродливый в том, что он был отключен, когда меня забивали другие приоритеты – в результате его можно было переписать для обработки любого количества сервисов, пользовательских путей журнала и cfg и т. Д.
  • Услуга, на которую она была написана, – это печально известный диспетчер очереди (spoolsv.exe).

Чтобы установить службу, используйте installutil.exe от MS. Убедитесь, что служба работает как «локальная системная учетная запись» или она не сможет запускать / останавливать службы.

appMon.cs:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.ServiceProcess; using System.Text; using System.Timers; using System.Windows.Forms; using System.IO; using System.Net.Mail; using System.Threading; using System.Management; namespace appMon { public class appMon : ServiceBase { public const string serviceName = "appMon"; public appMon() { InitializeComponent(); } private void InitializeComponent() { this.ServiceName = serviceName; } ///  /// Clean up any resources being used. ///  protected override void Dispose(bool disposing) { // free instantiated object resources not handled by garbage collector base.Dispose(disposing); } public static string getCurrUser() {// gets the owner of explorer.exe/UI to determine current logged in user String User = String.Empty; String Domain = String.Empty; String OwnerSID = String.Empty; string processname = String.Empty; int PID = Process.GetProcessesByName("explorer")[0].Id; ObjectQuery sq = new ObjectQuery ("Select * from Win32_Process Where ProcessID = '" + PID + "'"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(sq); foreach (ManagementObject oReturn in searcher.Get()) { string[] o = new String[2]; oReturn.InvokeMethod("GetOwner", (object[])o); User = o[0]; System.IO.StreamWriter sr = new System.IO.StreamWriter(@"C:\user.txt"); sr.WriteLine("\\" + o[2] + "\\" + o[1] + "\\" + o[0]); return User; } return User; } public static int readConfigFile() { int cputime = 5; // 5 min dflt try { string readcfg; readcfg = File.ReadAllText(@"c:\appMon\cpuUtilization.txt"); cputime = Convert.ToInt16(readcfg); return cputime; } catch (Exception e) { MessageBox.Show(e.ToString()); return cputime; // 5 min dflt } } public static void logEvents(bool spoolerHang, bool appHang, string msg) { try { StreamWriter sw; sw = File.AppendText(@"c:\appMon\appMonLog.txt"); sw.WriteLine(@"appMon spoolsv.exe event: " + "," + System.Environment.MachineName + "," + System.DateTime.Now + "," + msg); sw.Close(); } catch (Exception e) { MessageBox.Show(e.ToString()); } } ///  /// Start this service. ///  protected override void OnStart(string[] args) {// upon appMon load, a polling interval is set (in milliseconds 1000 ms = 1 s) System.Timers.Timer pollTimer = new System.Timers.Timer(); pollTimer.Elapsed += new ElapsedEventHandler(pollTimer_Elapsed); pollTimer.Interval = 20000; // 20 sec pollTimer.Enabled = true; } public static void StartService(string serviceName, int timeoutMilliseconds) { ServiceController service = new ServiceController(serviceName); try { TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); if (service.Status == ServiceControllerStatus.Stopped) // if service is not running... { service.Start(); // ...start the service } } catch(Exception e) { MessageBox.Show(e.ToString()); } } public static void StopService(string serviceName, int timeoutMilliseconds) { ServiceController service = new ServiceController(serviceName); try { TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds); if (service.Status == ServiceControllerStatus.Running) // if service is running... { service.Stop(); //...stop the service } service.WaitForStatus(ServiceControllerStatus.Stopped, timeout); } catch (Exception e) { MessageBox.Show(e.ToString()); } } public static void delFiles(string path) { string[] filePaths = Directory.GetFiles(path); foreach (string filePath in filePaths) { try { File.Delete(filePath); } catch (Exception e) { // TODO: !log to file instead! MessageBox.Show("error deleting files: " + e.ToString()); } } } public static void getServiceInfo(string serviceName) { ServiceController service = new ServiceController(serviceName); ServiceController[] depServices = service.ServicesDependedOn; List depServicesList = new List(); foreach (ServiceController sc in depServices) { depServicesList.Add(sc.ServicesDependedOn.ToString()); logEvents(false, false, sc.ServicesDependedOn.ToString()); } } void pollTimer_Elapsed(object sender, ElapsedEventArgs e) {// polling interval has elapsed getServiceInfo("spooler"); ServiceController serviceSpooler = new ServiceController("spooler"); if (serviceSpooler.Status == ServiceControllerStatus.Stopped) { logEvents(true, false, "Print Spooler is: " + serviceSpooler.Status.ToString()); serviceSpooler.Refresh(); serviceSpooler.Start(); logEvents(true, false, "Print Spooler is: " + serviceSpooler.Status.ToString()); } int cputime = readConfigFile(); // get active processes (exe's, including services) Process[] processlist = Process.GetProcesses(); // iterate through process list foreach (Process theprocess in processlist) { // assign local variable to iterator - cures the foreach "gotcha" Process p = theprocess; if (p.ProcessName == "spoolsv") // "spoolsv" = windows name for spoolsv.exe aka "spooler" { if (p.TotalProcessorTime.Minutes > cputime) // has current spooler thread occupied >= cputime # mins of CPU time? { logEvents(true, false, "spoolsv.exe CPU time (mins): " + p.TotalProcessorTime.Minutes.ToString()); p.Refresh(); StopService("spooler", 0); StartService("spooler", 0); } } } } ///  /// Stop this service. ///  /// protected override void OnStop() { } } } 

Команда sc предоставляет отличный способ автоматизации управления сервисами. Для вызова из кода просто выполните Process.Start("sc", "args") и перенаправьте вывод, если хотите получить результат.

Эта одна строка сообщает службе перезапустить дважды после ожидания 1 мин. при сбое. Через один день он сбрасывает счетчик сбоев. Вы также можете настроить его для запуска программ и т. Д. При последующих сбоях.

 sc failure myservice reset= 86400 actions= restart/60000/restart/60000// 

http://technet.microsoft.com/en-us/library/cc742019(v=ws.10).aspx