关于以前写的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);
}
运行后,类似这样:
任何分区上的任何变化都会诱发事件(通常是由于文件变化而造成磁盘分区可用空间的变化)。
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盘的可用空间发生变化,事件才会执行):
当然,WQL的功能远远不止这些,这篇文建也是简单的讨论一下。