WMI 包装器






4.75/5 (5投票s)
一个提供 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
,都有其对应的集合类,名称相同并在末尾加上 s(CIM_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
对象集合。其中每个对象都是计算机上的文件或打印机共享,支持Path
或AccessMask
等属性,以及Delete
等方法。CreateFileShare
、DeleteFileShare
允许创建或删除文件共享,而无需调用GetShares
。
计算机控制
提供了 Reboot
和 Shutdown
方法。必须先调用 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_ACE
、Win32_SecurityDescriptor
和 Win32_Trustee
)不属于集合,可以从头创建。请参阅 Computer.vb 中 CreateFileShare
函数的代码,了解如何使用它们。
方法已实现。它们返回一个 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:第一个公开版本。