创建 WMI 方法

若要创建某个 WMI 方法,请为该方法定义输入和输出参数。 输入和输出参数由特殊的 WMI 系统类 __PARAMETERS 表示。 有关详细信息,请参阅调用方法编写方法提供程序

本主题包括以下部分:

在 MOF 中创建 WMI 类方法

在 WMI 中,提供程序方法通常是与类表示的对象相关的不同操作。 不要更改属性的值来执行操作,而应该创建一个方法。 例如,可以使用 EnableDisable 方法来启用或禁用 Win32_NetworkAdapter 表示的网络信息中心 (NIC)。 虽然这些操作可以表示为读/写属性,但建议的设计是创建一个方法。 或者,如果你要使类的状态或值可见,则建议的方式是创建读/写属性而不是方法。 在 Win32_NetworkAdapter 中,NetEnabled 属性使适配器的状态可见,但状态之间的更改由 Enable 或 Disable 方法执行。

类声明可以包括一个或多个方法的声明。 你可以选择继承父类的方法,也可以实现自己的方法。 如果你选择实现自己的方法,则必须声明该方法并使用特定的限定符标记来标记该方法。

以下过程说明如何在不从基类继承的类中声明方法。

声明方法

  1. 在类声明的大括号之间定义方法名称,后接任何限定符。

    以下代码示例说明方法的语法。

    [Dynamic, Provider ("ProviderName")]
    class ClassName
    {
        [Implemented] <ReturnType> <MethodName>
            ([ParameterDirection, IDQualifier] 
            <ParameterType> <ParameterName>);
    };
    
  2. 完成后,通过调用 MOF 编译器将托管对象格式 (MOF) 代码插入 WMI 存储库。

    有关详细信息,请参阅编译 MOF 文件

以下列表定义方法声明的元素。

Provider

将特定的提供程序链接到类说明。 Provider 限定符的值是提供程序的名称,向 WMI 告知支持方法的代码所在的位置。 提供程序还应使用 Dynamic 限定符来标记任何具有动态实例的类。 相反,请不要使用 Dynamic 限定符来标记包含具有 Implemented 方法的静态实例的类。

Implemented

声明你实现一个方法,而不是从父类继承方法实现。 默认情况下,WMI 会将父类的实现传播到派生类,除非派生类提供实现。 省略 Implemented 限定符表示该方法在该类中没有实现。 如果重新声明一个没有 Implemented 限定符的方法,WMI 仍会假设你不打算实现该方法,调用该方法时,会调用父类方法实现。 因此,仅当你在方法中添加或删除限定符时,在派生类中重新声明方法而不附加 Implemented 限定符才有用。

ReturnType

描述方法返回的值。 方法的返回值必须是布尔值、数字、CHAR、STRING、DATETIME 或架构对象。 还可以将返回类型声明为 VOID,表示方法不返回任何内容。 但是,不能将数组声明为返回值类型。

MethodName

定义方法的名称。 每个方法必须有唯一的名称。 WMI 不允许一个类或类层次结构中存在两个具有相同名称和不同签名的方法。 因此,也不能重载方法。

ParameterDirection

包含用于描述参数是输入参数、输出参数还是这两种类型的限定符。 不要多次使用同一参数名称作为输入参数或多次使用同一参数名称作为输出参数。 如果同一参数名称同时出现在 In 和 Out 限定符中,则功能在概念上等同于在单个参数中使用 In、Out 限定符。 但是,当使用单独的声明时,输入和输出参数在所有其他方面必须完全相同(包括 ID 限定符的数量和类型),此外,限定符必须相同且已为这两个参数显式声明。 强烈建议在单个参数声明中使用 In、Out 限定符。

IDQualifier

包含 ID 限定符,用于唯一标识参数顺序中每个参数在方法中的位置。 默认情况下,MOF 编译器会自动使用 ID 限定符来标记参数。 编译器将第一个参数标记为值 0(零),将第二个参数标记为值 1(一),依此类推。 如有必要,可以在 MOF 代码中显式指明 ID 顺序。

ParameterType

描述方法可以接受的数据类型。 可以将参数类型定义为任何 MOF 数据值,包括数组、架构对象或引用。 使用数组作为参数时,请使用未绑定的数组或具有显式大小的数组。

ParameterName

包含参数的名称。 此时还可以选择定义参数的默认值。 缺少初始值的参数将保持未分配状态。

以下代码示例说明参数列表和限定符。

[Dynamic, Provider ("ProviderX")]
class MyClass
{
    [Implemented] 
    sint32 MyMethod1 ([in, id(0)] sint32 InParam);
    [Implemented] 
    void MyMethod2 ([in, id(0)] sint32 InParam, 
       [out, id(1)] sint32 OutParam);
    [Implemented] 
    sint32 MyMethod3 ([in, out, id(0)] sint32 InOutParam);
};

以下代码示例说明如何在 MOF 参数中使用数组。

[Dynamic, Provider ("ProviderX")]
class MyClass
{
    [Implemented] 
    sint32 MyMethod1 ([in, id(0)] Win32_LogicalDisk DiskParam[]);
    [Implemented] 
    sint32 MyMethod2 ([in, id(0)] Win32_LogicalDisk DiskParam[32]);
};

以下代码示例说明如何使用架构对象作为参数和返回值。

[Dynamic, Provider ("ProviderX")]
class MyClass
{
    [Implemented] sint32 MyMethod1 ([in, id(0)] Win32_LogicalDisk 
        DiskParam);
    [Implemented] 
    Win32_LogicalDisk MyMethod2 ([in, id(0)] string DiskVolLabel);
};

以下代码示例说明如何包含两个引用:一个引用指向 Win32_LogicalDisk 类的实例,另一个引用指向未知对象类型的实例。

[Dynamic, Provider("ProviderX")]
class MyClass
{
    [Implemented] 
    sint32 MyMethod1 ([in, id(0)] Win32_LogicalDisk ref DiskRef);
    [Implemented] 
    sint32 MyMethod2 ([in, id(0)] object ref AnyObject);
};

在 C++ 中创建 WMI 类方法

以下过程说明如何以编程方式创建 WMI 类方法。

以编程方式创建 WMI 类方法

  1. 创建方法所属的类。

    在创建方法之前,首先必须有一个用于放置该方法的类。

  2. 使用 IWbemServices::GetObjectGetObjectAsync 检索 __PARAMETERS 系统类的两个子类。

    使用第一个子类描述输入参数,使用第二个子类描述输出参数。 如有必要,可以执行一次检索,然后调用 IWbemClassObject::Clone 方法。

  3. 使用一个或多个 IWbemClassObject::Put 调用将输入参数写入第一个类,将输出参数写入第二个类。

    在描述方法的参数时,请遵循以下规则和限制:

    • 将 [in, out] 参数视为单独的条目,其中一个参数位于包含输入参数的对象中,另一个位于包含输出参数的对象中。

    • 除 [in, out] 限定符外,其余限定符必须完全相同。

    • 指定从 0(零)开始的 ID 限定符,为每个参数指定一个。

      输入或输出参数的顺序由每个参数的 ID 限定符值确定。 所有输入参数必须位于所有输出参数的前面。 在更新现有方法提供程序时更改方法输入和输出参数的顺序可能会导致调用该方法的应用程序失败。 在现有参数的末尾添加新的输入参数,而不要按照已建立的顺序插入新参数。

      确保 ID 限定符顺序中没有空隙。

    • 将返回值作为名为 ReturnValue 的属性放入输出参数类中。

      这会将该属性标识为方法的返回值。 此属性的 CIM 类型是方法的返回类型。 如果方法的返回类型为 void,则根本没有 ReturnValue 属性。 此外,ReturnValue 属性不能像方法参数那样具有 ID 限定符。 将 ID 限定符分配到 ReturnValue 属性会生成 WMI 错误。

    • 表达类中属性的任何默认参数值。

  4. 通过调用 IWbemClassObject::PutMethod 将两个 __PARAMETERS 对象放入父类中。

    调用 PutMethod 一次即可将两个 __PARAMETERS 对象放入类中。

创建类