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

WMI:MOF 基础

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.57/5 (8投票s)

2008年7月18日

CPOL

10分钟阅读

viewsIcon

87592

downloadIcon

967

托管对象格式的简短介绍。

引言

WBEM (Web-Based Enterprise Management) 是一个旨在实现企业环境管理标准化的行业倡议。WBEM 包含由 DMTF (Distributed Management Task Force) 开发和维护的一系列标准。WMI (Windows Management Instrumentation) 是 Microsoft 对 WBEM 的实现,被系统管理员和开发人员广泛用作管理 Windows 系统的工具。

WMI 使用 CIM (Common Information Model) 标准来表示各种 Windows 组件。CIM 是一种信息模型,用于描述可供管理的企业元素。CIM 有两个重要部分:CIM 规范和 CIM 模式。

CIM 模式包含一组代表可管理实体的类。它的核心模型包含最高抽象级别的类,如 CIM_ManagedElementCIM_SettingCIM_Location。这些类的派生用于组成 CIM 模式通用模型,每个模型描述一个不同的管理领域(例如,系统、用户、网络、应用程序等)。每个通用模型都用作特定平台扩展的基础,这些类代表您可以用于管理的具体、真实世界的元素。

CIM 规范定义了可用于表达管理模型的元素。其中一些元素是

  • 模式。模式是一组具有单个所有者的类。每个类名都包含模式名。例如,CIM_DataFileWin32_ProcessMSFT_WmiCoreEvent 类属于名为 CIMWin32MSFT 的模式。
  • 。类是定义对象类共有的属性和方法的原型。
  • 属性。属性描述类的数据。
  • 方法。方法描述类的行为。
  • 限定符。限定符提供有关类、属性和方法的附加信息。CIM_DataFile.Name 属性有一个名为“Key”的布尔类型限定符,其值为 True

CIM 规范定义了模型的语法和规则,包括称为 MOF (Managed Object Format) 的 CIM 语法语言。在本文中,我将尝试介绍 MOF 用法的基本知识,并提供一些简单的示例。

Microsoft CIM 实现

WMI 是 Microsoft 对 CIM 的实现。要使模型正常工作,它需要包含两个组件:CIM 存储库和 CIMOM (CIM Object Manager)。存储库存储类定义,在某些情况下也存储实例定义(但这是一个例外——大多数实例定义由 WMI 提供程序动态检索)。对于 Windows 系统,存储库位于 %Windir%\System32\wbem\repository 目录(通常是 c:\windows\system32\wbem\repository\)。

CIMOM 是存储库和管理数据使用者之间的对象代理:它服务于消费者对数据检索、修改或添加到存储库的请求。Microsoft 对 CIMOM 的实现是一个名为 WinMgmt.exe 的 Windows 服务,也位于 %Windir%\System32\wbem 目录(或 c:\windows\system32\wbem\)。

WMI 消费者是与 WMI 交互的任何应用程序。WMI 提供程序是 DLL,它动态地将各种 Windows 子系统中的管理数据提供给 WMI。

使用示例

MOF 文件是一个文本文件,其中包含一系列类和实例定义。每个定义都以分号 (;) 结尾。MOF 文件还可以包含注释和编译指示指令。

要将 MOF 文件中包含的对象定义添加到 WMI 存储库,您需要一个名为 mofcomp.exe 的工具(也位于 %Windir%\System32\wbem 目录中)。Mofcomp.exe 支持许多控制其行为的命令行开关,但其基本语法是

mofcomp FileName.mof

如果没有错误,此命令会将 Filename.mof 中的类和实例定义添加到 WMI 存储库。

WMI 工具

Wbemtest.exe 是一个 WMI 测试工具,随每个 Windows 安装一起分发。您可以通过在命令提示符下键入“wbemtest”或从“开始”->“运行”->“wbemtest”来调用它。一个更用户友好的 WMI 工具名为 CIM Studio,可从 Microsoft 网站免费下载。如果您尚未安装 CIM Studio,我建议您安装它并在使用 WMI 时使用它。

启动 CIM Studio 后,会显示一个对话框,允许您选择要连接的 WMI 命名空间。连接后,会显示两个主窗格:右侧窗格是一个树形视图,表示所选命名空间中类的层次结构视图。在右侧窗格中,您可以查看类或实例详细信息。使用 CIM Studio,您可以添加、修改或删除 WMI 类或实例,编译 MOF 文件,从现有类生成 MOF 代码等。

创建 WMI 命名空间

WMI 存储库中的类以命名空间的层次结构组织。此层次结构的根是 Root 命名空间,它包含几个子命名空间,其中一个是众所周知的:CimV2 命名空间,WMI 操作的默认命名空间。尽管在使用本文提供的示例时可以使用 CimV2 命名空间,但最好创建一个新命名空间,您可以向其中添加类和实例,而不会影响 WMI 功能的其余部分。

这是将新命名空间添加到 WMI 的示例 MOF 代码

#pragma namespace("\\\\.\\Root")

instance of __Namespace
{
    Name = "MOFNamespace";
};

要添加新命名空间,您需要执行以下操作

  • 将上下文更改为您将要创建子命名空间的命名空间。为此,您可以使用 #pragma namespace 指令。在这种情况下,将在 Root 下创建一个子命名空间。除了 #pragma namespace,您还可以使用 -N mofcomp 开关。
  • 使用“instance of”关键字创建 __Namespace WMI 系统类的新实例。
  • Name 属性的新实例设置为新命名空间的名称。在本例中为“MOFNamespace”。

使用 mofcomp.exe 编译上述 MOF 后,您将拥有一个新的 WMI 命名空间:Root\MOFNamespace。如果您使用 Wbemtest 或 CIM Studio 浏览新创建的命名空间,您会发现它是空的,除了自动添加到每个新命名空间的一些 WMI 系统类。

删除 WMI 命名空间

使用新创建的命名空间 (MOFNamespace) 进行测试后,您可以使用包含以下文本的 MOF 文件将其删除

#pragma namespace("\\\\.\\Root")

#pragma deleteinstance
    ("__Namespace.Name='MOFNamespace'", FAIL)

要删除 WMI 命名空间

  • 使用 #pragma namespace 指令将 mofcomp 上下文更改为您要删除的命名空间的父命名空间。
  • 使用 #pragma deleteinstance 指令删除实例。#deleteinstance 接受 WMI 对象路径作为参数,因此请为其提供要删除的 __Namespace 实例的路径。

编译上述 MOF 文件将删除指定的命名空间及其所有内容,因此请谨慎使用。您需要严格遵守 WMI 对象路径,因此不能使用空格

"__Namespace.Name = 'MOFNamespace'"

使用 mofcomp.exe 编译时,将产生以下错误

An error occurred while processing item 1:
Error Number: 0x8004103a, Facility: WMI
Description: Invalid object path
Compiler returned error 0x80041001

如果您尝试删除的命名空间不存在且使用了 FAIL,则会报告另一个错误

An error occurred while processing item 1:
0X80041002 Class, instance, or property '__Namespace.Name='MOFNamespace'' was not found.
Compiler returned error 0x80041001

创建基类

你们中的大多数人可能熟悉一些 WMI 类,例如 Win32_ProcessCIM_DataFileWin32_Service。这是一个示例 MOF 文件,可让您创建自己的 WMI 类

#pragma namespace("\\\\.\\Root\\MOFNamespace")

class Test_BaseClassWithNoProperties
{
};
  • 使用 #pragma namespace 将 mofcomp 上下文更改为您要创建新类的命名空间。除了 #pragma namespace,您还可以使用 mofcomp -N 命令行开关。如果您不指定命名空间,新类将在 Root\Cimv2 中创建。
  • 使用“class”关键字让 mofcomp 知道您正在创建新类,后跟类名。按照惯例,类名由下划线分隔的两部分组成:类所属的模式和类名本身(例如,在 CIM_DataFile 中,CIM 是模式名,DataFile 是类名)。
  • 使用一对匹配的花括号将类体括起来。

上述 MOF 代码,当用 Mofcomp.exe 编译时,在 Root\MOFNamespace 下创建一个名为“Test_BaseClassWithNoProperties”的新 WMI 类。由于我们没有为我们的类指定任何自定义属性,它只包含一组预定义的 WMI 系统属性。我们没有指定新类的父类,因此它将作为基类创建:它的 __Superclass 系统属性将为空。

向 WMI 类添加属性

这是一个创建类并为其添加一些属性的示例 MOF 代码

#pragma namespace("\\\\.\\Root\\MOFNamespace")

class Test_ClassWithProperties
{
    [Key] uint32 KeyProperty;
    string StringProperty;
    boolean BoolProperty = false;
    sint32 ArrayProperty [];    
};

要向 WMI 类添加属性,在类体中,为每个属性指定以下格式的属性列表

  • 将属性限定符列在方括号中。例如,如果您以:'[Key]' 开头属性声明,则该属性将被标记为该类的键属性。限定符是可选的。
  • 声明属性数据类型。您可以在 CIM 规范中找到可用数据类型的列表。
  • 声明属性名称。
  • 如果属性有默认值,您可以在属性名称后指定该值。
  • 如果属性是数组,请在属性名称后加一对方括号。要指定固定长度数组,请在方括号之间放置数组长度。

创建层次结构

CIM 规范遵循面向对象的范式——您可以通过在子类名称后指定父类名称来为给定类创建子类

class Test_DerivedClassTwo : Test_DerivedClassOne
{
    boolean BoolProperty;
    string  ArrayProperty [];       
};

使用 MOF 创建派生 WMI 类

  • 使用“class”关键字,后跟新类名。
  • 指定父类名,用冒号分隔。
  • 在类体中,列出派生类的新属性。

在上面的示例中,Test_DerivedClassTwo 继承了所有 Test_DerivedClassOne 属性,并添加了两个。

创建关联类

关联是 CIM 模式的重要组成部分。要创建关联类,您需要创建一个用 Association 限定符标记的类,其中包含对感兴趣的实例类的引用。这是一个示例 MOF 代码

[Association : ToInstance]
class Test_AssociationClass
{
    [Key] Test_GroupComponent ref GroupComponent;
    [Key] Test_PartComponent ref PartComponent;
};

要创建关联类

  • 在类声明前加上“Association”类限定符。
  • 向类添加两个引用类型属性。引用指向关联类正在绑定的实例类(Test_GroupComponentTest_PartComponent)。

创建类实例

这是一个创建 WMI 类实例的示例 MOF

instance of Test_ClassWithProperties
{
    KeyProperty = 5;
    StringProperty = "String Value";
    ArrayProperty = {1, 2, 3, 4, 5};
    // BoolProperty is False by default
};

要创建类的实例

  • 使用“instance of”关键字,后跟类名。
  • 指定具有适当值的属性列表。如果属性有默认值,并且您没有设置其值,它将设置为默认值。数组值用花括号括起来。

结论

这里介绍的所有 WMI 类都是静态的,它们的实例及其定义都存储在 WMI 存储库中。这不常见:大多数 WMI 类是动态的——只有类定义存储在存储库中,而实例由底层 WMI 提供程序动态检索。

MOF 语法并不难:它由一系列类和实例定义组成,用于描述要移动到 CIMOM 的对象。但你为什么要使用它呢?对于大多数常见应用程序,标准的 WMI 用法,无论是通过 System.Management .NET 命名空间还是 WMI 脚本库,都已足够,你根本不需要了解 MOF。另一方面,使用 MOF 创建动态 WMI 类,如果没有创建底层 WMI 提供程序(这很困难),则毫无用处。然而,在某些场景中,你可以使用上述技术来解决一些实际问题,我希望在接下来的几篇文章中展示其中一些。

最后说明

本文是对 MOF 的一个非常简短且不完整的介绍——更完整的文档可以在 DMTF 官方网站(我特别推荐 DMTF 教程)和 MSDN 中找到。为了进行比较,除了示例 MOF 文件,我还包含了 C# 和 VBScript 示例——对我来说,使用 MOF 比相应的 C# 或 VBScript 代码要容易得多。

最后,这里有一些有用的链接

© . All rights reserved.