发布经典提供程序的事件架构
经典 提供程序应使用 托管对象格式 (MOF) 来发布其事件数据的布局。 然后,使用者可以在运行时从 WMI 读取已发布的布局,并使用它来读取事件数据。
如果使用 MOF 在 WMI 中发布事件数据的布局,通常会在 root\wmi 命名空间中创建以下三种类型的 MOF 类:
提供程序 MOF 类
如果发布事件数据的布局,则必须创建用于标识提供程序的 MOF 类。 此类必须派生自 EventTrace MOF 类,并且必须为空, (没有) 任何属性或方法。 类还必须包含唯一标识提供程序的 Guid 限定符。 这与调用 RegisterTraceGuids 函数注册提供程序时使用的 GUID 相同。
事件 MOF 类
事件 MOF 类定义提供程序提供的事件类。 此类派生自提供程序 MOF 类,并且必须为空, (没有) 属性或方法。 类还必须包含 Guid 限定符,该限定符唯一标识其子类定义的事件类。 在设置 EVENT_TRACE_HEADER 结构的 Guid 成员时,提供程序使用相同的 GUID。
事件类型 MOF 类
事件类型 MOF 类定义实际事件数据。 此类派生自其父事件 MOF 类。 命名事件类型 MOF 类时,约定是在事件类型 MOF 类名称的开头使用事件 MOF 类名称。 例如,如果事件 MOF 类名称为 HWConfig,而事件类型 MOF 类表示 CPU 信息,则应将事件类型命名为 MOF 类,HWConfig_CPU。
使用事件类型 MOF 类上的 EventType 限定符来标识事件类型。 如果多个事件类型使用相同的事件数据,则可以使用相同的 MOF 类。 在设置 EVENT_TRACE_HEADER 结构的 Class.Type 成员时,提供程序使用相同的事件类型值来标识 事件 。
事件类型 MOF 类包含属性。 这些属性的顺序定义事件数据的布局。 下表标识了可用于定义属性的数据类型和限定符。 有关可以使用的属性和类限定符的详细信息,请参阅 事件跟踪 MOF 限定符。
数据类型 | 限定符 | 说明 |
---|---|---|
sint8、 uint8 | 格式 | 声明一个 1 字节的十进制整数。 若要声明 ANSI 字符,请使用 格式 限定符并将其值设置为“c”。 |
sint16、 uint16 | 格式 | 声明一个 2 字节的十进制整数。 若要指示数字是十六进制数字,请使用 格式 限定符。 例如,格式化 (“x”) 。 |
sint32、 uint32 | 格式 | 声明一个 4 字节的十进制整数。 若要指示数字是十六进制数字,请使用 格式 限定符并将其值设置为“x”。 |
sint64、 uint64 | 格式 | 声明一个 8 字节的十进制整数。 若要指示数字是十六进制数字,请使用 格式 限定符并将其值设置为“x”。 |
boolean | 声明布尔值。 事件使用者应将值解释为 BOOL (4 字节整数) 。 | |
char16 | 声明宽字符。 事件使用者应将内核事件中的 char16 数组解释为宽字符串。 (使用数组大小复制字符串。某些字符串可能包含前导 NULL 字符。) | |
对象 | 扩展名 | 声明二进制 Blob。 扩展限定符指示 Blob 中的数据类型。 |
string | Format、 StringTermination | 声明字符串值。 若要指示字符串是宽字符字符串,请使用 格式 限定符并将其值设置为“w”。 如果未指定 格式 限定符,则字符串被视为 ANSI 字符串。 若要指示字符串的终止方式,请使用 StringTermination 限定符。 |
若要指定数组,可以使用方括号 []。 方括号可以包含数组的大小。 例如:
[WmiDataId(1), read] uint8 MyGuid[16];
还可以使用 Max 限定符指定数组的大小。 例如:
[WmiDataId(1), Max(16), read] uint8 MyGuid[];
如果在方括号中包含数组的大小,则 MOF 编译器将为你生成 Max 限定符。
请务必对每个属性使用 说明 限定符。 说明应包含使用者在显示属性值时可以使用的显示名称。
以下示例演示描述提供程序、事件和事件类型 MOF 类的 MOF 文件的内容。
#pragma namespace("\\\\.\\root\\wmi")
[dynamic: ToInstance, Description("Defines my event provider"),
Guid("{7C214FB1-9CAC-4b8d-BAED-7BF48BF63BB3}")]
class MyProvider : EventTrace
{
};
[dynamic: ToInstance, Description("Defines a category of events that my provider logs."): Amended,
Guid("{B49D5931-AD85-4070-B1B1-3F81F1532875}")]
class MyCategory : MyProvider
{
};
[dynamic: ToInstance, Description("Defines an event within the category of events that my provider logs."): Amended,
EventType(1)]
class MyCategory_MyEvent : MyCategory
{
[WmiDataId(1), Description("Cost factor"): Amended, read] sint32 Cost;
[WmiDataId(2), Description("Index values"): Amended, read] uint32 Indices[3];
[WmiDataId(3), Description("Signature"): Amended, read, StringTermination("NullTerminated"), Format("w")] string Signature;
[WmiDataId(4), Description("Is complete copy"): Amended, read] boolean IsComplete;
[WmiDataId(5), Description("Class identifier"): Amended, read, Extension("Guid")] object ID;
};
请注意,提供程序、事件和事件类型 MOF 类名称在整个命名空间中必须是唯一的。 为了避免命名冲突,应对所有类名使用唯一的描述性名称。 类属性还应是描述性的,并且在其类层次结构中是唯一的, 包含与父类相同的属性名称的子类会覆盖父类的 属性。
定义 MOF 类后,使用 MOF 编译器生成事件架构并将其添加到 CIM 存储库。 然后,使用者可以从存储库读取架构,并以编程方式读取事件数据。 有关 MOF 语法和使用 MOF 编译器 (Mofcomp.exe) 将 MOF 类添加到 CIM 存储库的完整说明,请参阅 托管对象格式。 有关使用 Wbemtest.exe 访问 CIM 存储库的信息,请参阅 Windows Management Instrumentation (WMI) 。
版本控制 MOF 类
如果添加或更改事件类型 MOF 类,约定是同时对事件 MOF 类及其子事件类型 MOF 类进行版本控制。 若要对当前事件 MOF 类进行版本控制,请将_Vn追加到类名称,其中 n 是从 0 开始的增量数字。 如果这是类的第一个修订版本,请将_V0追加到类名。 还必须将 EventVersion 限定符添加到 类。 使用在类名中用于 EventVersion 限定符值的同一版本号。
新版本的事件 MOF 类必须使用与原始类相同的名称和 Guid 限定符。 新类可以选择添加 EventVersion 限定符。 不包含 EventVersion 限定符的事件 MOF 类被视为最新版本,或者如果类的所有版本都包含 EventVersion 限定符,则版本号最高的类被视为最新版本。 提供程序使用 EVENT_TRACE_HEADER 结构的 Class.Version 成员来标识跟踪中包含的事件的版本。
以下示例演示如何对事件 MOF 类进行版本控制。
#pragma namespace("\\\\.\\root\\wmi")
#pragma classflags("forceupdate")
[dynamic: ToInstance, Description("Defines my event provider"),
Guid("{7C214FB1-9CAC-4b8d-BAED-7BF48BF63BB3}")]
class MyProvider : EventTrace
{
};
[dynamic: ToInstance, Description("Defines a category of events that my provider logs."),
Guid("{B49D5931-AD85-4070-B1B1-3F81F1532875}"),
EventVersion(1)]
class MyCategory : MyProvider
{
};
[dynamic: ToInstance, Description("Defines an event within the category of events that my provider logs."): Amended,
EventType(1),
EventName("MyEvent")]
class MyCategory_MyEvent : MyCategory
{
[WmiDataId(1), Description("Cost factor"): Amended, read] sint32 Cost;
[WmiDataId(2), Description("Index values"): Amended, read] uint32 Indices[3];
[WmiDataId(3), Description("Signature"): Amended, read, StringTermination("NullTerminated"), Format("w")] string Signature;
[WmiDataId(4), Description("Is complete copy"): Amended, read] boolean IsComplete;
[WmiDataId(5), Description("Identifier"): Amended, read, Extension("Guid")] object ID;
[WmiDataId(6), Description("Buffer Size"): Amended, read] uint32 Size;
};
[dynamic: ToInstance, Description("Defines a category of events that my provider logs."): Amended,
Guid("{B49D5931-AD85-4070-B1B1-3F81F1532875}"),
EventVersion(0)]
class MyCategory_V0 : MyProvider
{
};
[dynamic: ToInstance, Description("Defines an event within the category of events that my provider logs."): Amended,
EventType(1)]
class MyCategory_V0_MyEvent : MyCategory_V0
{
[WmiDataId(1), Description("Cost factor"): Amended, read] sint32 Cost;
[WmiDataId(2), Description("Index values"): Amended, read] uint32 Indices[3];
[WmiDataId(3), Description("Signature"): Amended, read, StringTermination("NullTerminated"), Format("w")] string Signature;
[WmiDataId(4), Description("Is complete copy"): Amended, read] boolean IsComplete;
[WmiDataId(5), Description("Identifier"): Amended, read, Extension("Guid")] object ID;
};