c# - System.Management.ManagementEventWatcher - 从断开连接中恢复

标签 c# .net wmi monitoring

我正在尝试构建一个可以通过 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 事件。尽管链接断开,但附加到 ManagementEventWatcher 的 ManagementScope 对象仍将 IsConnected 显示为 true。

有没有人知道如何检查连接状态?

此时我唯一能想到的就是使用 ManagementScope 对象定期对机器执行 WMI 查询并确保它仍然有效,尽管这只能检查本地->远程连接而不是对应的远程->本地连接。我想我可以查找另一个我可以用来验证连接的 WMI 查询(假设查询有效),但这似乎比我应该做的工作更多。

最佳答案

WMI 中有两种事件使用者 - 临时和永久。您可能正在寻找的是永久事件订阅。这是关于 MSDN 的简短介绍

永久消费者是一个 COM 对象,可以随时接收 WMI 事件。永久事件使用者使用一组持久对象和筛选器来捕获 WMI 事件。就像临时事件使用者一样,您可以设置一系列 WMI 对象和过滤器来捕获 WMI 事件。当与筛选器匹配的事件发生时,WMI 加载永久事件使用者并通知它有关该事件的信息。因为永久消费者是在 WMI 存储库中实现的,并且是在 WMI 中注册的可执行文件,所以只要 WMI 正在运行,永久事件消费者在创建后甚至在操作系统重新启动后都会运行并接收事件。有关详细信息,请参阅始终接收事件。

这篇 MSDN 文章应该足以让您继续前进 http://msdn.microsoft.com/en-us/library/aa393014(VS.85).aspx .

但是,在我处理这个问题的情况下,我们选择轮询数据而不是创建永久消费者。另一种选择是监视某些事件(例如重启),然后重新注册您的临时事件使用者。

关于c# - System.Management.ManagementEventWatcher - 从断开连接中恢复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1162121/

相关文章:

c# - 在 SQL Server 2005 中加载 CRL 程序集 : The given assembly name or codebase was invalid.(HRESULT 异常:0x80131047)

c# - 为什么我的 Catch block 仅在 Visual Studio 中调试时运行?

c# - 为什么需要 JsonRequestBehavior?

c# - 给定一个类型,如何确定它装箱的类型?

C# 数组最大值

c# - 从 DirectoryInfo.GetFiles 返回的 FileInfo 没有指向文件?

c# - 如何从内存中运行下载的文件?

c# - 在 C# 中更改本地管理员密码

c# - 通过WMI C#Active Directory

c# - 如何删除 C# 中的 Windows 还原点?