在过去的几年中,发现在.NET中编写WMI应用程序总是显得有些繁琐。不禁想,是否有更好的方法来编写.NET中的WMI应用程序。因此,开始在互联网上搜索任何可能有助于加快开发过程的东西。无论在哪里搜索,都能找到一篇又一篇的文章,展示人们如何使用.NET中的System.Management命名空间来实现他们的目标。其中一些文章写得很好,有些可能需要更多的工作。但它们都有一个共同点,那就是文章后面的评论字符串,询问“该如何做‘这个’…”或“是否可能做‘这个’…”。这让思考,这篇文章真的回答了人们的问题吗?找到的答案是,是的,也不是。
编写.NET中的WMI应用程序的一个问题是,没有直接的方法来处理内置类的属性和方法。每个解决方案都以开发者通过字符串索引引用ManagementObject对象中的属性而告终。
C# ManagementObject oMngObject = MyObejctCollection[0];
lblDemo.Text = oMngObject["Manufacturer"];
这是一个完全有效的方法来处理WMI属性,但如果不知道想要访问的属性的名称,这并没有多大好处。这就是EasyWMI的用武之地。
开发了EasyWMI类库,以帮助加快开发WMI驱动应用程序的开发过程。它包括root/cimv2命名空间中的大部分Win32类。该库由两个主要部分组成:控制器和模型。模型是直接从Windows中的WMI提取的Win32类,并包含每个类的属性和方法。控制器是创建和填充每个类的模型。对于每个模型,都有一个相应的控制器。控制器的命名方案与模型的命名方案相同,只是没有前缀Win32_。例如,Win32_Process类有一个相应的控制器名为Process。使用EasyWMI源代码时需要注意的一点是,并没有实际编写所有的模型和控制器。实际上使用CodeDOM编写了一个代码生成器,专门用于这个目的。因此,在处理实际源代码时,请注意,缩进可能会有些偏差,这可能会使阅读变得有点尴尬,但并不难。
使用EasyWMI非常简单。创建一个想要使用的类控制器的新实例,并运行SelectAll()方法。每个控制器包含5个重载的构造函数;默认构造函数假设为“localhost”。
C# // 创建ComputerSystem的新实例。
ComputerSystem CS = new ComputerSystem();
IList<win32_computersystem> CSCollection = CS.SelectAll();
Win32_ComputerSystem MyCS = CSCollection[0];
SelectAll()返回一个泛型的IList<t>集合,类型为Win32_CLASSNAME。有些类只会在集合中返回一个项目,例如ComputerSystem和OperatingSystem。现在可以访问Win32_ComputerSystem类型的特定对象的所有方法和属性。对于返回多个对象的类,可以简单地使用foreach循环遍历集合。
C# static void DisplayLogicalDisks(IList<win32_logicaldisk> Drives)
{
SetupSection("Logical Disks");
try
{
foreach (Win32_LogicalDisk LogicalDisk in Drives)
{
Console.WriteLine("Drive " + LogicalDisk.DeviceID);
Console.WriteLine("Volume:\t\t" + LogicalDisk.VolumeName);
Console.WriteLine("Size:\t\t" + ConvertToMB(LogicalDisk.Size));
Console.WriteLine("Free Space:\t\t" + ConvertToMB(LogicalDisk.FreeSpace));
Console.WriteLine("File System:\t" + LogicalDisk.FileSystem);
Console.WriteLine("Caption:\t\t" + LogicalDisk.Caption);
Console.WriteLine("Serial:\t\t" + LogicalDisk.VolumeSerialNumber);
Console.WriteLine();
}
}
catch (Exception ex)
{
Console.WriteLine("Error retrieving information.");
Console.WriteLine("Message: " + ex.Message);
}
Console.WriteLine();
}
现在已经知道如何简单地访问Win32类中的每个属性,但如何使用它们的方法呢?简单,就像使用任何方法一样。
C# string Domain;
string User;
Process SysProcess = new Process();
IList<win32_process> Processes = SysProcess.SelectAll();
foreach (Win32_Process Process in Processes)
{
if (Process.Name == "iexplore.exe")
{
Process.GetOwner(out Domain, out Username);
Process.Terminate(0);
}
}
也可以指定一个不同的查询来代替默认的select * from。
C# CS = new ComputerSystem(ComputerName);
CS.EasyWMICfgUsername = "@yourdomain\\username";
CS.EasyWMICfgPassword = "password";
CS.EasyWMICfgQuery = "select Manufacturer from";
CS.SetScope();
CSCollection = CS.SelectAll();
可能注意到在设置一些配置选项后调用了SetScope()方法。在运行SelectAll()方法之前,将需要运行SetScope()方法,任何时候更改任何配置选项。