.NET(C#): 再议WMI中的__InstanceModificationEvent事件查询_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > .NET(C#): 再议WMI中的__InstanceModificationEvent事件查询

.NET(C#): 再议WMI中的__InstanceModificationEvent事件查询

 2013/10/2 20:58:11  _Mgen  博客园  我要评论(0)
  • 摘要:关于以前写的WMI事件查询文章可以参考:.NET(C#):使用ManagementEventWatcher进行WMI事件查询.NET(C#):ManagementQuery类型构建WMI中的WQL选择查询和事件查询.NET(C#):使用WMI事件查询实现对进程和可移动磁盘的监控还有我的其他WMI文章。这里我就开门见山
  • 标签:事件 .net C# net instance

关于以前写的WMI事件查询文章可以参考:

.NET(C#):使用ManagementEventWatcher进行WMI事件查询

.NET(C#):ManagementQuery类型构建WMI中的WQL选择查询和事件查询

.NET(C#):使用WMI事件查询实现对进程和可移动磁盘的监控

还有我的其他WMI文章。

这里我就开门见山,__InstanceModificationEvent查询和之前总提到的__InstanceCreationEvent或者__InstanceDeletionEvent查询会有一些不同,因为如果不做适当的修饰的话,__InstanceModificationEvent会把所有指定类型的所有属性变化都会列举出来,这样会造成信息量过大。比如,我们来监控所有系统磁盘分区的变化。

注意:代码运行需引用System.Management.dll并且加入using System.Management;命名空间。

代码:

//注意:引用System.Management.dll 和 using System.Management;

static void Main(string[] args)

{

    //创建WQL事件查询

    var query = new WqlEventQuery("__InstanceModificationEvent",

        TimeSpan.FromSeconds(1),  //WHTHIN = 1

        "TargetInstance ISA 'Win32_LogicalDisk'");

 

    //创建事件查询的侦听器(ManagementEventWatcher)

    var watcher = new ManagementEventWatcher(query);

 

    //事件注册代码

    watcher.EventArrived += (sender, e) =>

    {

        Console.WriteLine("运行:{0}", GetInfo(e.NewEvent));

    };

 

    //异步开始侦听

    watcher.Start();

 

    Console.WriteLine("按任意键停止监控");

    Console.ReadKey(true);

}

 

static string GetInfo(ManagementBaseObject mobj)

{

    var instance = (ManagementBaseObject)mobj["TargetInstance"];

    return string.Format("{0} - {1}", instance["Name"], DateTime.Now);

}

 

运行后,类似这样:

image

任何分区上的任何变化都会诱发事件(通常是由于文件变化而造成磁盘分区可用空间的变化)。

 

WQL和SQL类似,所以可以随意加入一些元素来限制__InstanceModificationEvent事件查询的作用域,比如我们只去监控D盘,修改上面WQL查询如下:

var query = new WqlEventQuery("__InstanceModificationEvent",

    TimeSpan.FromSeconds(1),  //WHTHIN = 1

    "TargetInstance ISA 'Win32_LogicalDisk' AND TargetInstance.Name = 'D:'");

 

我们还可以直接监控一个属性的变化,诀窍就是使用WQL中的上一个实例对象:PreviousInstance。

比如我们只去监控D盘的可用空间变化(WMI中Win32_LogicalDisk类型的FreeSpace属性)。把上面的WQL查修成如下代码:

//创建WQL事件查询

var query = new WqlEventQuery("__InstanceModificationEvent",

    TimeSpan.FromSeconds(1),  //WHTHIN = 1

    "TargetInstance ISA 'Win32_LogicalDisk' AND TargetInstance.Name = 'D:' AND PreviousInstance.FreeSpace != TargetInstance.FreeSpace");

 

然后把上面代码中获取信息的方法GetInfo也修改下,为了增加对可用空间的输出,如下:

static string GetInfo(ManagementBaseObject mobj)

{

    var instance = (ManagementBaseObject)mobj["TargetInstance"];

    return string.Format("{0} - {1} - 剩余空间:{2:N} MB", instance["Name"], DateTime.Now, ((ulong)instance["FreeSpace"]) >> 20);

}

 

运行结果类似这样(只有D盘的可用空间发生变化,事件才会执行):

image

当然,WQL的功能远远不止这些,这篇文建也是简单的讨论一下。

发表评论
用户名: 匿名