Я пытаюсь создать приложение, которое может контролировать несколько удаленных машин через WMI. Как разработчик C #, я решил использовать пространство имен System.Management.
Из соображений производительности и масштабируемости я бы предпочел использовать метод сбора информации, основанный на событиях, а не метод опроса. Поэтому я исследовал класс ManagementEventWatcher.
Для простых задач мониторинга этот класс кажется именно тем, что я хочу. Я создаю объект, назначаю ему параметры ManagementScope, EventQuery и EventWatcherOptions, подписываюсь на событие EventArrived и вызываю метод Start (упрощенный пример ниже).
using SM = System.Management;
...
SM.ManagementEventWatcher _watcher;
SM.ConnectionOptions conxOptions;
SM.ManagementScope scope;
SM.WqlEventQuery eventQuery;
SM.EventWatcherOptions eventOptions;
SM.EventArrivedEventHandler handler;
string path = @"\\machine\root\cimv2";
conxOptions = new SM.ConnectionOptions ();
conxOptions.Username = user;
conxOptions.Password = password;
scope = new SM.ManagementScope (path, conxOptions);
scope.Connect ();
eventQuery = new SM.WqlEventQuery ("SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA 'Win32_Process'");
eventOptions = new SM.EventWatcherOptions ();
eventOptions.Context.Add ("QueryName", "Process Query");
_watcher = new SM.ManagementEventWatcher (scope, eventQuery, eventOptions);
handler = new SM.EventArrivedEventHandler (HandleWMIEvent);
_watcher.EventArrived += handler;
_watcher.Start ();
Console.WriteLine ("Press Any Key To Continue");
Console.ReadKey ();
_watcher.Stop ();
_watcher.EventArrived -= handler;
Проблема, с которой я сталкиваюсь, заключается в том, что трудно обнаружить, когда соединение с удаленной машиной было разорвано различными способами (перезапуск машины, сбой маршрутизатора, отключение сетевого кабеля и т. Д.).
Класс ManagementEventWatcher, по-видимому, не предоставляет каких-либо средств определения того, что соединение было потеряно, поскольку событие Stopped не будет срабатывать при этом. Объект ManagementScope, прикрепленный к ManagementEventWatcher, по-прежнему показывает IsConnected как true, несмотря на неработающую ссылку.
У кого-нибудь есть идеи как проверить состояние соединения?
Единственное, что я могу сделать на этом этапе, - это использовать объект ManagementScope для периодического выполнения запроса WMI к машине и убедиться, что он по-прежнему работает, хотя он может проверять только локальное-> удаленное соединение, а не соответствующее удаленное-> локальное соединение. Я полагаю, что мог бы найти другой WMI-запрос, который мог бы использовать для проверки соединения (при условии, что запрос работает), но это похоже на большую работу, чем я должен был сделать.