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

WMI 包装器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (5投票s)

2008年7月3日

CPOL

5分钟阅读

viewsIcon

49344

downloadIcon

1357

一个提供 WMI 类的 .NET 解决方案的包装器。

引言

WMI 是一项强大的技术,被程序员广泛用于管理计算机。在 .NET 中可以通过 System.Management 命名空间访问它。尽管 WMI 类结构高度统一,但通常的使用方式是通过 WQL 请求返回变体对象。本文中 WMIwrapper 项目的目的是提供与 root\CIMV2 命名空间中提供的 WMI 类等效的类。它实现了许多类及其属性和方法,因此程序员不必依赖无法在编译时验证的 WQL 字符串(例如 SELECT * FROM Win32_LogicalDisk),而是可以在 Visual Studio GUI 中使用 IntelliSense 来获取对象、属性和方法。

演示应用程序是一个快速粗略的概念验证。首先,使用文件/打开菜单连接到计算机(“.” 是本地计算机的默认值),然后在对象树中导航(并非所有类都包含在内,有关完整参考请参阅帮助文件)。屏幕的右侧面板显示了为找到的第一个实例返回的原生 WMI 类的所有属性及其值。屏幕底部显示了一个网格视图,其中包含相应包装器类的所有属性(不包括数组),每行一个实例(例如,每个驱动器一行)。比较这两个面板是调试包装器的快速有效的方法。

背景

基类是 WMIobject。它不存在于原生 WMI 中,但用于提供通用方法,主要用于将 WMI 类型转换为 .NET 类型并实现 WMI 方法。其他类遵循 WMI 架构继承自它。例如(“:” 表示“继承自”),Win32_ComputerSystem : CIM_UnitaryComputerSystem : CIM_ComputerSystem : CIM_System : CIM_LogicalElement: CIM_ManagedSystemElement : WMIobject。每个类实现一部分由最终类使用的属性和方法。通常,只有以 Win32 开头的类将在项目外部使用。

类数量庞大,无法在本篇文章中包含图表。您可以使用 Documentation.chm 文件,或创建类图来查看类的层次结构。实际的 WMI 类层次结构已得到尊重,并进行了少量调整,因为 WMI 支持多重继承,而 .NET 不支持。

类成对出现:每个对象类,例如 CIM_System,都有其对应的集合类,名称相同并在末尾加上 sCIM_Systems)。集合类主要提供查找项的属性:查询 WMI 最常见的方式是填充集合,然后枚举项。

我添加了一个名为 Computer 的额外类,以简化对其他类的访问。其用法将在下面详细介绍。

使用代码

计算机硬件和系统

包装器最简单的用法是通过 Computer 类。使用以下代码连接到计算机

Dim ComputerName As String = "."
Dim _Computer As New WMIwrapper.Computer(ComputerName)

您的 Windows 帐户必须具有连接到远程计算机的必要权限:您要么是域管理员,要么在工作组中拥有两个计算机上具有相同登录名和密码的帐户。

由于加载和运行 WMI 需要相当长的时间(通常一到两秒),因此默认情况下不运行查询。您必须使用方法来执行此操作。以下代码查询 Win32_Processors

' GetLogicalElements method queries WMI for hardware.
' The parameter is an enumeration for the hardware classes to query.
' WMIwrapper.Computer.LogicalElements.All is for all hardware.
_Computer.GetLogicalElements(WMIwrapper.Computer.LogicalElements.Processors)

现在,Processors 属性包含一个 Processor 对象集合。遍历它以读取其属性,例如 Caption

If _Computer.Processors IsNot Nothing Then
  For Each Win32_Processor As WMIwrapper.Win32_Processor In _Computer.Processors
    MsgBox(Win32_Processor.Caption)
  Next
End If

请参阅 Documentation.chm 以发现 Computer 类的所有方法和属性。

文件共享

Computer 方法允许管理文件共享(这在 .NET 中并不容易)

  • GetShares 填充 Shares 属性,这是一个 Share 对象集合。其中每个对象都是计算机上的文件或打印机共享,支持 PathAccessMask 等属性,以及 Delete 等方法。
  • CreateFileShareDeleteFileShare 允许创建或删除文件共享,而无需调用 GetShares

计算机控制

提供了 RebootShutdown 方法。必须先调用 GetOperatingSystem

使用 Win32 类

如果使用以 Win32 开头的类,则可以进行完全的 WMI 访问。通常,您会填充一个集合,然后遍历它

Dim _Processors As New WMIwrapper.Win32_Processors(ComputerName)
If _Processors IsNot Nothing Then
  For Each Win32_ProcessorI As WMIwrapper.Win32_Processor In _Processors
    MsgBox(Win32_ProcessorI.Caption)
  Next
End If

集合构造函数允许使用类的键值来选择单个项,或传递 WQL 条件

' Pass the key value
Dim _Shares As New WMIwrapper.Win32_Shares(ComputerName,"Admin$")
If _Shares IsNot Nothing Then
  For Each Win32_ShareI As WMIwrapper.Win32_Share In _Shares
    MsgBox(Win32_ShareI.Path)
  Next
End If

' Pass a WQL condition
Dim _Volumes As New WMIwrapper.Win32_Volumes(ComputerName, , "Caption = 'C:\\'")
If _Volumes IsNot Nothing Then
  For Each Win32_VolumeI As WMIwrapper.Win32_Volume In _Volumes
    MsgBox(Win32_VolumeI.DeviceID)
  Next
End If

少数类使用方式不同。安全类(Win32_ACEWin32_SecurityDescriptorWin32_Trustee)不属于集合,可以从头创建。请参阅 Computer.vbCreateFileShare 函数的代码,了解如何使用它们。

方法已实现。它们返回一个 InvokeError 对象,其中包含两个属性:Number(0 表示成功)和 Message

关注点

使用 MgmtClassGen.exe 可以用更少的精力获得类似的​​代码,但此工具为每个 WMI 类生成一个类,包括所有必要的代码。如果您大量使用 WMI,会得到大量冗余代码,这些代码应放在基类中。这正是 WMIwrapper 所做的。

EasyWMI 是一个类似的项目,并行开发。WMIwrapper 更接近原始 WMI 架构,所以我希望它将来更容易维护。我认为它更容易使用,因为文档是所有工作的重点。

致谢

我以 TechNet 作为类的参考。Microsoft 的 WMI 工具,尤其是 WMI CIM Studio 是理解继承的最便捷方式。

我使用 Sandcastle 通过 Sandcastle help file builder GUI 编译帮助文件。

历史

这是一个无休止的项目,因为一些类仍然缺失,并且 WMI 会随着新版本的 Windows 而发展。您可能会在代码中找到一些 'TODO 注释,用于非关键方法(例如,我不认为 WMI 是创建文件夹的最佳方法),我会在有时间时填充它们。无论如何,未来版本已有计划。

  • 版本 1.0:第一个公开版本。
© . All rights reserved.