2011-12-21 3 views
3

Я хочу, чтобы проверить, работает ли определенная служба (скажем, что она имеет отображаемое имя - ServiceA). Я хочу, чтобы моя программа проверяла каждые 5 минут, что служба все еще работает. Если все в порядке, он будет зацикливаться и ждать еще 5 минут, а затем снова проверить. Если он обнаружит, что ServiceA остановился, я хочу, чтобы программа отправила мне электронное письмо и сообщила ... ServiceA перестала работать. Ниже у меня есть код, который я сделал до сих пор, который способен вытащить все текущие службы и отобразить фактическое отображаемое имя на консоли. Какие-либо идеи о коде/логике нужны для того, что мне нужно выше?Пошлите мне сообщение, если служба окон прекращена

namespace ServicesChecker 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      ServiceController[] scServices; 
      scServices = ServiceController.GetServices(); 

      Console.WriteLine("Services running on the local computer:"); 
      foreach (ServiceController scTemp in scServices) 
      { 
       if (scTemp.Status == ServiceControllerStatus.Running) 
       { 
        Console.WriteLine(); 
        Console.WriteLine(" Service :  {0}", scTemp.ServiceName); 
        Console.WriteLine(" Display name: {0}", scTemp.DisplayName); 
       } 
      } 
      //Create a Pause.... 
      Console.ReadLine(); 
     } 
    } 
} 
+0

Что произойдет, когда шашка перестанет работать ...! –

+2

Windows уже может это сделать для вас. Вам не нужно писать приложение, чтобы инициировать действие, когда служба останавливается или терпит неудачу. –

+0

@ Коды: Hoes делает Windows это? – abatishchev

ответ

4

Помещенный имя каждого сервиса в массиве и проверить, если ваш разыскиваемый имя работает

List<string> arr = new List<string>();  
foreach (ServiceController scTemp in scServices) 
{ 
    if (scTemp.Status == ServiceControllerStatus.Running) 
    { 
     arr.add(scTemp.ServiceName); 
    } 
} 
if (arr.Contains("YourWantedName") 
{ 
    // loop again 
} 
else 
{ 
    // send mail 
} 
+0

Для фрагмента отправки почты с сайта c: http://social.msdn.microsoft.com/Форумы/en/netfxnetcom/thread/a75533eb-131b-4ff3-a3b2-b6df87c25cc8 Он должен содержать все необходимое для отправки простого сообщения. –

+1

Пожалуйста, никогда не предлагайте использовать не общие контейнеры, такие как 'ArrayList' в конце 2011 года! Вместо этого используйте generic, например 'List '. – abatishchev

+0

@abatishchev - какова была бы логика для кода цикла, чтобы я мог продолжать проверять массив на имя моего сервиса? –

0

Вам нужно будет отслеживать состояние службы, которые потребуют своего рода хранения. Самый простой, вероятно, является XML-файл, который отслеживает состояние службы, может быть, схема как этот

<services> 
<service name="service1" last-check="12/21/2011 13:00:05" last-status="running" /> 
... 
</services> 

Ваше приложение мониторинга, будет пробудиться найти статус услуг, которые она интересуется, и проверить, чтобы увидеть, что предыдущий статус службы. Если статус запущен, но в настоящее время остановлен, отправьте электронное письмо. Если служба не найдена, добавьте ее в список служб.

Сохранение статуса служб на диске защищает вас в случае, когда приложение для мониторинга отключается.

0

Heres пример службы, которая делает нечто похожее. Должно быть просто адаптировать его к вашим потребностям ..

public partial class CrowdCodeService : ServiceBase 
    { 
     private Timer stateTimer; 
     private TimerCallback timerDelegate; 
     AutoResetEvent autoEvent = new AutoResetEvent(false); 

     public CrowdCodeService() 
     { 
      InitializeComponent(); 
     } 
     int secondsDefault = 30; 
     int secondsIncrementError = 30; 
     int secondesMaximum = 600; 
     int seconds; 
     protected override void OnStart(string[] args) 
     { 
      Loggy.Add("Starting CrowdCodeService."); 
      timerDelegate = new TimerCallback(DoSomething); 
      seconds = secondsDefault; 
      stateTimer = new Timer(timerDelegate, autoEvent, 0, seconds * 1000); 
     } 

     static bool isRunning = false; 

     // The state object is necessary for a TimerCallback. 
     public void DoSomething(object stateObject) 
     { 
      if (CrowdCodeService.isRunning) 
      { 
       return; 
      } 
      CrowdCodeService.isRunning = true; 
      AutoResetEvent autoEvent = (AutoResetEvent)stateObject; 
      try 
      { 

       ////// Do your work here 


       string cs = "Application"; 
       EventLog elog = new EventLog(); 
       if (!EventLog.SourceExists(cs)) 
        { 
         EventLog.CreateEventSource(cs, cs); 
        } 
        elog.Source = cs; 
        elog.EnableRaisingEvents = true; 

        elog.WriteEntry("CrowdCodes Service Error:" + cmd.Message.ToString(), EventLogEntryType.Error, 991); 
       } 
      } 
      finally 
      {  
       CrowdCodeService.isRunning = false; 
      } 

     } 


     protected override void OnStop() 
     { 
      Loggy.Add("Stopped CrowdCodeService."); 
      stateTimer.Dispose(); 
     } 
    } 
2

Там нет необходимости перебирать все услуги, если вы знаете, какой из них вы ищете: вы можете instantiate ServiceController with the service name.

Что касается отправки электронной почты, ознакомьтесь с классом System.Net.Mail.MailMessage.

NB: Вы знаете, что вы также можете настроить службу для запуска действия, если оно не выполнено?

+0

, чтобы получить услугу для запуска действия - это означало бы, что вы могли бы инициировать ее отправку электронной почты, если она остановится? Как вы это делаете? –

+0

Найдите (или напишите) инструмент командной строки, который отправляет электронное письмо, и настройте его в соответствии с инструкциями, которые Коди Грей описал в своем комментарии к вашему вопросу. – Arnout

Смежные вопросы