65.9K
CodeProject 正在变化。 阅读更多。
Home

WMI 接口 for .NET

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.98/5 (43投票s)

2007年12月9日

CPOL

3分钟阅读

viewsIcon

140602

downloadIcon

2780

一个类库,用于辅助编写 WMI 应用程序。

Screenshot - EasyWMIDemo - click to enlarge

引言

在过去的几年里,我断断续续地编写了一些小型 WMI 应用程序,并且一直觉得用 .NET 编写这类应用程序总显得有些麻烦。我忍不住想,.NET 中一定有更好的方法来编写 WMI 应用程序。于是我开始在互联网上搜索任何可能有助于加快开发进程的内容。我到处都能找到文章,展示人们如何使用 .NET 中的 System.Management 命名空间来实现他们的目标。其中一些文章写得非常好,有些可能还有改进的空间。但它们都有一个共同点,那就是文章下方总有一些评论问:“如何实现‘这个’……”或“是否可能实现‘这个’……”。这让我思考,这篇文章是否真的解答了人们的疑问?我找到的答案是,是的,也否。

用 .NET 编写 WMI 应用程序的一个问题是,没有直接的方法来处理内置类的属性和方法。所有解决方案最终都让开发人员通过 ManagementObject 对象中的字符串索引来引用属性。

ManagementObject oMngObject = MyObejctCollection[0];
lblDemo.Text = oMngObject[“Manufacturer”];

虽然这是处理 WMI 属性的一种有效方法,但如果你不知道要访问的属性的名称,那么它就没什么用了。这就是 EasyWMI 的用武之地。

EasyWMI 详解

我开发了 EasyWMI 类库,以帮助加快开发 WMI 驱动应用程序的开发进程。它包含了root/cimv2命名空间中绝大多数的 Win32 类。该库主要包含两部分:控制器(controllers)和模型(models)。模型是直接从 Windows WMI 中提取的 Win32 类,包含每个类的所有属性和方法。控制器负责创建和填充每个模型。对于每个模型,都有一个相应的控制器与之对应。控制器的命名方案与模型的命名方案相同,只是去掉了前缀 Win32_ 。例如,Win32_Process 类有一个对应的控制器,名为 Process 。在使用 EasyWMI 的源代码时,需要注意一点,我并没有手动编写所有的模型和控制器。实际上,我为此目的构建了一个使用 CodeDOM 的代码生成器。所以在处理实际源代码时,请注意,缩进可能有些混乱,阅读起来会有些不方便,但并不困难。

Using the Code

使用 EasyWMI 非常简单。创建一个你想要使用的类控制器的实例,然后运行 SelectAll() 方法。每个控制器包含 5 个重载构造函数;默认构造函数假定为“localhost”。

// Create a new instance of ComputerSystem.
ComputerSystem CS = new ComputerSystem();
IList CSCollection = CS.SelectAll();
Win32_ComputerSystem MyCS = CSCollection[0];

SelectAll() 返回一个通用 IList<t /> 集合,类型为 Win32_CLASSNAME。某些类只返回集合中的一个项,例如 ComputerSystem OperatingSystem。现在你可以访问该特定 Win32_ComputerSystem 类型对象的全部方法和属性了。对于返回多个对象的类,你可以简单地使用 foreach 循环来遍历集合。

static void DisplayLogicalDisks(IList 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 类的属性有多么简单,那么如何使用它们的方法呢?很简单,就像使用任何方法一样使用它们。

string Domain;
string User;
Process SysProcess = new Process();
IList 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

CS = new ComputerSystem(ComputerName);
CS.EasyWMICfgUsername = @"yourdomain\username";
CS.EasyWMICfgPassword = "password";
CS.EasyWMICfgQuery = "select Manufacturer from";
CS.SetScope();
CSCollection = CS.SelectAll();

你可能会注意到,在设置了一些配置选项后,我调用了 SetScope() 方法。在运行 SelectAll() 方法之前,任何时候更改了配置选项,你都需要运行 SetScope() 方法。

结论

尽管这可能不是使用 .NET 与 WMI 接口的最完整、最好的方法,但我希望它能帮助简化 WMI 的使用并加快你的开发进程。

历史

目前还没有更新。

© . All rights reserved.