CIMTool 用于 Windows Management Instrumentation - 第 1 部分





5.00/5 (10投票s)
使用 WMI 检索有关您系统的信息并生成类,以方便 WMI 开发。
- 源代码: Harlinn.CIMTool-2013-02-17-01.zip - 1.6 MB
- 下载 Harlinn.CIMTool.Win-Binaries-Part4.zip - 70.8 KB
- 下载 Harlinn.CIMTool.Win-Binaries-Part3.zip - 2.4 MB
- 下载 Harlinn.CIMTool.Win-Binaries-Part2.zip - 5.6 MB
- 下载 Harlinn.CIMTool.Win-Binaries-Part1.zip - 5.1 MB
- 下载源代码和可执行文件: Harlinn.CIMTool-WPF-Preview-2013-02-21-02.zip - 4.1 MB
Harlinn.CIMTool-WPF-Preview-2013-02-21-02.zip 包含运行该工具在“Harlinn.CIMTool.Wpf\bin\Release”文件夹中所需的所有内容。 除非您对旧的 Windows Forms 版本感兴趣,否则无需下载其他压缩包。
下一篇 CIMTool 文章在此处找到: CIMTool for Windows Management Instrumentation - 第二部分[^]
第三部分在此处提供: CIMTool for Windows Management Instrumentation - 第三部分[^]
CIMTool WPF 版本预览
Harlinn.CIMTool-WPF-Preview-2013-02-21-02.zip 包含基于 Windows Presentation Foundation 的 CIMTool 版本预览。此版本仅依赖 .Net 4.0 和几个可免费获取的组件。此压缩包包含运行该工具在“Harlinn.CIMTool.Wpf\bin\Release”文件夹中所需的所有内容。

外部组件在此处找到
WPF 版本可用于浏览 WMI 命名空间、类、属性和限定符 – 因此对于浏览 WMI 提供的可用定义很有用。
要查询 WMI 类的实例,请在树视图中选择该类,然后右键单击选中的项。然后您可以从弹出菜单中选择“查询”。
我仍在进行代码生成的工作...
public class IIsApplicationPool : IIsObject { public IIsApplicationPoolProcessorSettings Cpu { get { System.Management.ManagementObject managementObject = GetObject("Cpu"); IIsApplicationPoolProcessorSettings element = (IIsApplicationPoolProcessorSettings) IIsWebAdministrationClassFactory.CreateObject(managementObject, false); return element; } set { Write("Cpu", value.ManagementObject); } } public IIsApplicationPoolFailureSettings Failure { get { System.Management.ManagementObject managementObject = GetObject("Failure"); IIsApplicationPoolFailureSettings element = (IIsApplicationPoolFailureSettings) IIsWebAdministrationClassFactory.CreateObject(managementObject, false); return element; } set { Write("Failure", value.ManagementObject); } } }
代码生成与 Microsoft 的 mgmtclassgen 的结果大不相同,其中一个更方便的功能是该工具生成的代码反映了 WMI 的面向对象特性。

要生成代码,您需要右键单击“类”窗格中的一个命名空间,然后选择“生成代码”项。

要使用生成的代码,您需要创建一个新的 c# 类库并添加对 Harlinn.CIMTool.Mgmt.dll 程序集的引用。代码生成器为 WMI 命名空间中的所有 WMI 类创建类。
引言
CIMTool 允许您浏览通过 Windows Management Instrumentation API 提供的信息。
您还可以使用 CIMTool 为 WMI 类生成 c# 代码。
如果您只想试用该工具,请将 Harlinn.CIMTool.Win-Binaries-Part1.zip、Harlinn.CIMTool.Win-Binaries-Part2.zip、Harlinn.CIMTool.Win-Binaries-Part3.zip 和 Harlinn.CIMTool.Win-Binaries-Part4.zip 的内容解压到一个单独的目录中。可执行文件名为 Harlinn.CIMTool.Win.exe。

这是我构建的一个工具,因为我需要探索 WMI,因为有些查询没有返回预期的信息,而且我发现 WMI 工具有点难以使用。
CIMTool 是使用 DevExpress 的 Windows Forms 组件构建的,如果您没有订阅,您可以从 DevExpress 下载一个 30 天免费的 DevExpress Universal Trial [^]。
Windows Management Instrumentation
WMI 提供了一个接口,允许本地和远程应用程序从计算机系统、网络或企业获取管理信息。
.png)
WMI 暴露了托管对象和 WMI 提供程序提供的信息,而 WMI 提供程序是一个监视一个或多个托管对象的 COM 对象。托管对象是物理或逻辑组件,例如网络适配器、数据库系统、操作系统或进程。
WMI 提供程序为 WMI 提供托管对象的信息,并将来自 WMI 的消息传递给托管对象。WMI 提供程序由一个 DLL 文件和一个 Managed Object Format (MOF) 文件组成,该文件定义了提供程序公开信息或执行操作的类。
WMI 基础结构是 Windows 操作系统的一个组成部分,由两个组件组成:WMI 服务(包括 CIM Object Manager)和 WMI 存储库。

WMI 存储库组织成一组命名空间。最初,WMI 服务创建诸如 root\default、root\cimv2 和 root\subscription 等命名空间,并安装一组默认的类定义,包括 Win32 类和 WMI 系统类。
Common Information Model (CIM) 使用面向对象的技巧提供数据的一致定义和结构。CIM 包括对必须呈现给管理应用程序的常见元素的表达式,如类、属性、方法和关联。

CIMTool
CIMTool 允许您仔细查看 WMI 托管类结构。

“类”窗格允许您浏览 WMI 公开的命名空间和类。此功能通过一组表示树中显示的各种节点类型的类来实现。

从专业角度来看,开发暴露元数据关于元数据的软件是非常迷人的。
抽象的 NodeBase 类实现了 DevExpress.XtraTreeList.TreeList.IVirtualTreeListData 接口
public void VirtualTreeGetCellValue(DevExpress.XtraTreeList.VirtualTreeGetCellValueInfo info) { if (info.Column.FieldName == "Name") { info.CellData = GetNodeName(); } } public void VirtualTreeGetChildNodes(DevExpress.XtraTreeList.VirtualTreeGetChildNodesInfo info) { System.Collections.IList theChildren = GetNodeChildren(); if (theChildren != null) { info.Children = theChildren; } } public void VirtualTreeSetCellValue(DevExpress.XtraTreeList.VirtualTreeSetCellValueInfo info) { info.Cancel = true; }
这是节点类层次结构中唯一与用于显示 WMI 命名空间和类的控件相关的代码。
NodeBase 建立了一个基础设施,使我们能够管理用于导航 WMI 公开的信息模型的对象图。
protected virtual NodeBase GetNodeParent() { return null; } protected abstract string GetNodeName(); protected abstract System.Collections.IList GetNodeChildren();
GetNodeRootNamespace 使我们能够通过层次结构向上导航到代表 WMI 存储库的 "\\.\ROOT" 命名空间的 NodeRootNamespace 对象。
internal virtual RootNamespace GetNodeRootNamespace() { NodeBase theParent = GetNodeParent(); if (theParent != null) { return theParent.GetNodeRootNamespace(); } return null; }通过在 NodeRootNamespace 中重写 GetNodeRootNamespace()
internal override RootNamespace GetNodeRootNamespace() { return this; }
我们有效地返回了所需的对象。
NamedNodeBase 引入了一个 Name 属性并重写了 GetNodeName() 方法
public abstract class NamedNodeBase : NodeBase { string name; public string Name { get { return name; } set { if (name == value) return; name = value; } } protected override string GetNodeName() { return Name; } }
NamespaceNode
每个 CMI 命名空间都由一个 NamespaceNode 表示

NamespaceNode 表示一个 WMI 命名空间,提供对命名空间中包含的类和子命名空间的访问。
public class NamespaceNode : NamedNodeBase { List<NamedNodeBase> children; NamespacesNode parent; ManagementScope managementScope;
在 .Net 中,System.Management.ManagementScope 表示一个 WMI 命名空间。
internal virtual string GetManagementScopePath() { if (Parent != null) { return string.Format("{0}\\{1}",Parent.GetManagementScopePath(),Name); } return @"\\.\ROOT"; } private void Connect() { ConnectionOptions connectionOptions = new ConnectionOptions(); connectionOptions.EnablePrivileges = true; string managementScopePath = GetManagementScopePath(); managementScope = new ManagementScope(managementScopePath, connectionOptions); managementScope.Connect(); }
GetManagementScopePath() 返回一个包含命名空间路径的字符串,我们在初次访问 ManagementScope 时通过 ManagementScope 属性进行连接。
public ManagementScope ManagementScope { get { if (managementScope == null) { Connect(); } return managementScope; } }
除根命名空间外,所有命名空间都位于另一个命名空间内,Parent 属性提供对表示同级命名空间集合的 NamespacesNode 的访问。
public NamespacesNode Parent { get { return parent; } set { if (parent == value) return; parent = value; } }
现在我们有了一个真正有父对象的对象,我们重写了 GetNodeParent() 方法,返回父节点的引用。
protected override NodeBase GetNodeParent() { return Parent; }
NamespaceNode 有两个子节点:一个 NamespacesNode 和一个 ClassesNode。
protected override System.Collections.IList GetNodeChildren() { if (children == null) { children = new List<NamedNodeBase>(); children.Add(new NamespacesNode(this)); children.Add(new ClassesNode(this)); } return children; } }
ClassesNode

ClassesNode 是命名空间中所有类的容器。
public List<ClassNode> Items { get { if (children == null) { children = new List<ClassNode>(); ManagementObjectSearcher searcher = new ManagementObjectSearcher (ManagementScope, new WqlObjectQuery("select * from meta_class"), null); using (searcher) { foreach (ManagementClass managementClass in searcher.Get()) { string className = managementClass["__CLASS"].ToString(); if (className.StartsWith("__") == false) { ClassNode classNode = new ClassNode(this, className, managementClass); children.Add(classNode); } } } foreach (ClassNode child in children) { child.ProcessInheritance(); } } return children; } }
我们通过查询 meta_class 元素来检索命名空间中包含的类,值得注意的是,返回的元素实际上是 ManagementClass 对象。
NamespacesNode
NamespacesNode 是命名空间中所有命名空间的容器。

protected override System.Collections.IList GetNodeChildren() { List<NamespaceNode> result = new List<NamespaceNode>(); ObjectGetOptions options = new ObjectGetOptions(); ManagementPath path = new ManagementPath("__NAMESPACE"); ManagementClass managementClass = new ManagementClass(ManagementScope, path, options); using (managementClass) { ManagementObjectCollection instances = managementClass.GetInstances(); using (instances) { foreach (ManagementObject mo in instances) { string namespaceName = mo.GetString("Name"); NamespaceNode namespaceNode = new NamespaceNode(); namespaceNode.Parent = this; namespaceNode.Name = namespaceName; result.Add(namespaceNode); } } } return result; }
我们通过检索命名空间中 "__NAMESPACE" 类的所有实例来填充 NamespacesNode。
ClassNode
ClassNode 表示一个 ManagementClass 对象。

ClassNode 表示一个 ManagementClass 对象,提供对 WMI 类的属性、基类、派生类和限定符的访问。
如果您在层次结构中选择一个类,则可以通过菜单的“文件 -> 新建 -> 查询”命令来访问该类的数据。

到目前为止,这已经证明是一个有用的实用程序,在下一篇文章中,我们将仔细研究 CIMTool 如何呈现从查询中检索到的数据。
历史
- 2013 年 2 月 1 日 - 初次发布。
- 2013 年 2 月 2 日 - 添加了二进制文件
-
2013 年 2 月 17 日 - 现在支持代码生成
只需右键单击树视图中的一个类,然后从弹出菜单中选择“生成类”。
代码经过了彻底的重构,代码生成器基于原始的 MS 代码生成器,这将发生变化。