§1 背景介绍
WMI Provider:对 WMI 对象的定义和操作,包含 MOF 和 DLL 文件。其中,MOF (Managed Object Format,托管对象格式) 中定义了 WMI 的命名空间或类,及类中的属性和方法; DLL 文件进行类实例的增删查改、类方法的实现。
详见:Designing Managed Object Format (MOF) Classes - Windows applications | Microsoft Docs
§2 使用 C++ 建立 MOF 文件
2.1 建立命名空间
2.1.1 介绍
- WMI 中所有命名空间实质上是系统类 __Namespace 中的一个实例, __Namespace 仅有一个属性 Name 。在建立命名空间时需要指定一个以字母开头,由字母、数字、下划线组成的名称,区分大小写,且不能与已有命名空间名称重复。
我们可以建立如下格式的命名空间:Root/myCompany/myProduct
- 在建立命名空间时,我们可以选择在已有的命名空间下建立 (Child Namespace) ,或是在根目录下建立 (Sibling Namespace) 。
官方不建议建立 Child Namespace ,因为在其 Parent Namespace 的模式更新时,所有类实例将被重建,这可能会导致我们建立的命名空间被删除。因此,在我们不能直接控制 Parent Namespace 时,建立 Sibling Namespace 更为保险。
2.1.2 操作步骤
使用 MOF 文件建立命名空间需要三步:
- 在最前面插入
#pragma namespace
表示之后的代码在哪个命名空间生效; - 在 __Namespace 类中建立一个实例;
- 保存为 .mof 文件,使用 mofcomp 工具 (在
%Windir%\System32\wbem
目录中) 编译。
之后查看 WMI 就可以看到建立的命名空间了。
2.1.3 代码示例
#pragma autorecover
#pragma namespace("\\\\.\\Root")
instance of __Namespace
{
Name = "MyNamespace";
};
为了保证我们定义的命名空间、类能够在 WMI 遇到错误重启时能够恢复,我们需要在 MOF 文件第一行加入 #pragma autorecover
。
2.1.4 本节详见
主要内容:
- Creating Hierarchies Within WMI - Windows applications | Microsoft Docs
- mofcomp - Windows applications | Microsoft Docs
- Using WMI Management Tools | Microsoft Docs
更多关于子命名空间、使用 WMI API 实现:
- Creating a Child Namespace with MOF Code - Windows applications | Microsoft Docs
- Creating a Namespace with the WMI API - Windows applications | Microsoft Docs
2.2 建立类
2.2.1 介绍
- 在 WMI 中存在基类和派生类。当很多派生类有着同样的属性时,可以将这些属性和方法放进基类中。
- 类的名称需要以字母开头,前后端不能使用下划线,由字母、数字、下划线组成,区分大小写,命名规则一致。好的命名应该是 “厂商名称_描述” 的构造形式。
例如:Kabuto_Security
- 类本身在 Provider 运行时不会被更改,只能在 WMI 服务停止时被修改。
2.2.2 操作步骤
以下仅说明使用 MOF 文件建立基类的方法,需要三步:
- 在最前面插入
#pragma namespace
表示之后的代码在哪个命名空间生效; - 插入以 class 为开头的代码段,内附字段和方法;
- 保存为 .mof 文件,使用 mofcomp 工具编译。
之后查看 WMI 就可以看到建立的基类了。
2.2.3 代码示例
#pragma autorecover
#pragma namespace("\\\\.\\Root\\Kabuto")
class Kabuto_Configuration
{
[key] string code;
string rootPath;
};
其中,[key] 主键表示实例的唯一性,一个类也可以有多个主键,详见 Adding a Qualifier - Windows applications | Microsoft Docs 。
2.2.4 本节详见
主要内容:
更多关于派生类、修饰符、添加方法、别名、使用 C++ 实现:
- Creating a WMI Derived Class - Windows applications | Microsoft Docs
- Creating a WMI Method - Windows applications | Microsoft Docs
- Creating a WMI Alias - Windows applications | Microsoft Docs
- Adding a Qualifier - Windows applications | Microsoft Docs
§3 C# 对 WMI 类实例的增删查改
以下所有操作都需要先建立 WMI 命名空间的连接,进入需要操作的类。
// 进入 WMI 中刚才建立的 "root\\Kabuto" 命名空间
ManagementScope managementScope = new managementScope("root\\Kabuto");
managementScope.Connect();
// 进入需要操作的类,需要指定命名空间
ManagementClass newClass = new ManagementClass("Kabuto_Security")
{
Scope = managementScope
};
3.1 增改类实例
本节及之后两节主要使用 .NET 中的 System.Management
命名空间来实现与 WMI 的交互,因此程序开头需要 using System.Management;
。
// 新建实例
ManagementObject newInstance = newClass.CreateInstance();
newInstance["code"] = "001";
newInstance["rootPath"] = "C:/";
// 提交更改
newInstance.Put();
当主键值不存在时,新增实例;当主键值存在时,更新实例。
3.2 删除类实例
// 获取所有实例
ManagementObjectCollection collection = newClass.GetInstances();
foreach (ManagementObject obj in collection)
{
if (obj["code"].ToString() == "001")
{
// 删除实例
obj.Delete();
break;
}
}
3.3 查询类实例
// 获取所有实例
ManagementObjectCollection collection = newClass.GetInstances();
Console.WriteLine(collection.Count);
foreach (ManagementObject obj in collection)
{
// 打印实例信息
Console.WriteLine(obj["code"]);
Console.WriteLine(obj["rootPath"]);
}
§4 总结
本文为初探 WMI ,仅能满足简单需求,后续需要的学习还有很多。
更多资料详见: