WMI概述
WMI作为Windows 2000操作系统的一部分提供了可伸缩的,可扩展的管理架构.公共信息模型(CIM)是由分布式管理任务标准协会(DMTF)设计的一种可扩展的、面向对象的架构,用于管理系统、网络、应用程序、数据库和设备。Windows管理规范也称作CIM for Windows,提供了统一的访问管理信息的方式。利用WMI,可以监视、跟踪和控制有关软件应用程序、硬件组件和网络的系统事件,将来自不同来源的数据用通用、标准且逻辑上有组织的方式映像出去,以便在管理数据之间建立相互关系和关联,而不必考虑这些数据的类型、内容或来源.
使用WMI还会带来以下便利之处:
统一的编程API:所有的管理对象定义在基于CIM的对象模型的公共的对象框架下.脚本或者应用程序可以使用一种API(WMI)访问完全不同的来源的信息,这些信息的来源可能是Win32 API,Windows NT事务日志,注册表,计数器,设备驱动,SNMP和活动目录等等.
远程管理:对于应用程序和脚本来说,定义在WMI中的管理对象在本地和远程都是可用的,尤其是管理远程的对象并不需要特别的工作.
可发现和导航:应用程序和脚本通过枚举可用的类来发现系统的那些信息是可用的.您也可以检测相关联的对象之间的关系并且详细的研究其中的一个是怎么影响其他的对象的;
查询:WMI管理数据就像关系数据库一样的,您可以使用SQL查询语句那样过滤和选取您感兴趣的数据;
强大的事件发布和订阅:您可以对系统中的管理对象的任何变化而请求事件,或者那些不被内部事件所支持的外部事件.事件的订阅者可以对特定的事件请求通知,这样胜于接受在原始的开发过程中预定义的一系列事件.这种结构使得任何用户定义的动作在给定的事件中开始.
WMI技术组成
WMI由以下几部分组成:
管理架构
这部分包括CIM对象管理器和CIM对象储存库,主要用于储存模式定义和提供者绑定信息.特别的,数据是动态的从提供者命令获取的.
WMI提供者
WMI提供者使用系统提供的任何管理接口提取系统的管理信息,它作为操作系统、服务、应用程序、或者设备驱动程序等与 CIMOM 之间的中间代理程序。通过各种 COM 接口,提供程序可向 WMI 提供数据,处理来自系统管理应用程序的请求,并生成事件通知。提供程序还将管理信息和接口映射到 CIM 储存库中定义和存储的对象类。
WMI使用者
使用者组件和应用程序通过CIMOM监视WMI事件,允许您在事件收到的时候执行动作.“使用者”是系统管理应用程序(如 Microsoft Systems Management Server (SMS))或第三方应用程序或脚本。使用者只需要知道它们打算获取其信息的对象的类。信息的来源以及实际获取信息的方式无关紧要,它们被隐藏起来。使用者可以获取有关计算机、操作系统、应用程序和设备的信息,以及获取可通过其他管理协议得到的信息。
公共信息模型 (Common Information Model, CIM) 储存库
“CIM 储存库”是一个对象数据库,用于存储定义的对象,如用于访问和操作系统管理信息的静态类定义和实例。
公共信息模型对象管理器 (Common Information Model object manager, CIMOM)
CIM 储存库由 CIMOM 管理,它形同对象请求的代理程序。CIMOM 跟踪可用的类并决定由哪一个提供程序负责提
供这些类的实例。CIMOM 和 CIM 储存库由称为 WinMgmt 的系统服务表示,可通过一组 COM 接口访问。
WMI架构
图三描述了完整的Windows管理规范WMI的架构,其中还包括了WMI的使用者和提供者的例子.图3的顶部是一些管理应用程序(WMI的使用者)的例子,除了图上的使用者之外可能还包括基于浏览器的web程序,Microsoft管理控制台或定制的Win32程序.
WMI架构的核心由CIM对象管理器和CIM储存库以及Win32环境的WMI提供者组成.CIM对象管理器处理数据提供
者个数据的使用者之间的信息通讯,就如SMS管理控制台或者报表程序调用WMI脚本API.CIM对象存储库拥有CIM的模式,当对象管理器为应用程序对CIM对象的请求服务时将使用到这些模式.
定制的Win32程序通过访问COM接口与CIM对象管理器交互来完成管理的请求,而其他的应用程序将通过访问方法,
诸如ODBC,ADSI接口或者Windows设备管理规范脚本API(也叫做WBEM脚本)来处理这些请求.
图形的下面部分描述了管理对象和与其关联的提供者,如windows
WMI 管理对象的信息查询和方法访问
管理对象的信息查询和方法访问
在这一节内容,我们将通过几个实例来学习如何查询管理对象信息和访问管理对象提供的方法,这一部分内容将使用到我们在前面讲述到的System.Management命名空间中的相关类对象。
管理对象的信息查询
管理对象的信息查询有两种方式,一种是直接枚举管理对象的各种属性,而获取我们感兴趣的数据;一种方法是通过SQL查询语句的方式来过滤冗余的数据,而得到感兴趣的数据。
对于一个Win32_LogicalDisk实例对象而言,它有那些属性,也就是它有那些信息可以供我们访问呢?这些属性名是什么样的?这是开发人员在开发过程中经常遇到的问题,通常我们是可以去查MSDN,但是在这里我给出一种通过编程的方法获取代码。
*****************************************************
//获取Win32_LogicalDisk WMI对象可供访问的属性
public static void FetchProperties()
{
ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk");
diskClass.Get();
Console.WriteLine("Win32_LogicalDisk对象共有" + diskClass.Properties.Count + " 属性。");
. PropertyDataCollection diskProperties = diskClass.Properties;
foreach (PropertyData diskProperty in diskProperties)
{
Console.WriteLine("diskClass[{0}] ",diskProperty.Name);
}
}
*****************************************************
知道了那些属性可以供我们访问,下一步就是来具体的获取管理对象Win32_LogicalDisk的信息。首先用第一种方法,即枚举属性而回去数据的方法。在这里我们通过列举WMI类Win32_LogicalDisk实例对象的数据,获取您的计算机上各种逻辑磁盘分区,包括软驱和光驱,并输出每个逻辑磁盘分区的一些信息。
*****************************************************
//获取Win32_LogicalDisk对象的数据信息
public static void FetchInfo()
{
ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk");
ManagementObjectCollection disks = diskClass.GetInstances();
foreach (ManagementObject disk in disks)
{
Console.WriteLine("Disk_DeviceID= {0}" ,disk["DeviceID"].ToString());
Console.WriteLine("Disk_Name = {0}" , disk["Name"].ToString());
if(disk["FileSystem"]!=null)
Console.WriteLine("Disk_FileSystem = {0}" , disk["FileSystem"].ToString());
Console.WriteLine("Disk_Description = {0}" , disk["Description"].ToString());
if(disk["Size"]!=null)
Console.WriteLine("Disk_Size ={0} " ,System.Convert.ToInt64(disk["Size"].ToString()));
Console.WriteLine("Disk_type = {0}" , System.Convert.ToInt16(disk["DriveType"].ToString()));
}
}
*****************************************************
提示:(1)由于你的软驱和光驱的FileSystem和Size属性为空,所有加了if判断,否则输出会产生异常。
(2)Size属性的数据是以bytes字节为单位。
上面访问的方法其实很简单,我们再看看如何通过SQL查询的方式来访问管理对象的数据。以下的例子是以win32_Process管理对象为例。
*****************************************************
//通过SQL查询方式访问管理对象数据
public static void QueryInfo()
{
ManagementObjectSearcher searcher = new
ManagementObjectSearcher("select * from Win32_Process");
foreach (ManagementObject process in searcher.Get())
{
Console.WriteLine("process = " + process["Name"]);
}
}
*****************************************************
至此,我们可以轻松的通过上面的方式访问管理对象的数据了。
管理对象方法的访问
在Windows2000的任务管理器中,我们可以终止进程,也可以启动进程;在服务管理器中,我们可以启动、暂停、7终止服务,那么您肯定会问通过程序怎样完成类似上面的任务。是的,对于那些可供用户操作的管理对象,它提供可一些公开的方法供客户端应用程序来调用,从而完成各种任务。上面的例子只是给出了单向的信息访问,接下来的内容,我们将看看如何访问管理对象的方法。
并不是所有的管理对象会公开方法,是否公开方法和公开那些方法取决于需要。对于逻辑磁盘来说,可能会公开一个Format的方法用于格式化磁盘,对于运行的进程来说,可能公开Start、Stop方法来开始终止进程。我们将以启动一个进程为例来说明这个问题。
创建一个进程,需要调用Win32_Process WMI对象的Create方法。Create方法有四个输入参数,分别为:
uint32 Create(
string CommandLine,
string CurrentDirectory,
Win32_ProcessStartup ProcessStartupInformation,
uint32* ProcessId
);
CommandLine参数为进程的可执行文件全名,如启动一个记事本Notepad.exe;
CurrentDirectory为被启动进程的当前工作目录,若为Null,则子进程和父进程之间共享一个