分享
 
 
 

WMI使用说明(翻译)

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

文:http://www.codeproject.com/useritems/wmi.asp

第一次翻译,只想带个头,翻译的不好,希望各位不要笑话我

相信大家对WMI一定也都有听说过吧,国内的很多网站也多有介绍过

这里是codeproject上的一篇,我觉得很全面在这里翻译一下希望大

家评价一下,讨论一下自己编写代码的心得,OK不多说了,翻译了......

先介绍一下相关知识:

什么是WMI呢Windows 管理规范 (Windows Management Instrumentation ),它的

主要功能包括:访问本地主机的一些信息和服务,可以远程管理计算机(当然你必

须拥有足够的权限)也就是说可以象重起,关机,关闭进程,创建进程等等!

有了初步了解下面我门开始一些初步的工作吧:

在这个WMI程序中,我将实现四个基本功能:

1.Explorer 类似与windows里的资源管理器

2.SystemInfo 查看你的硬件信息和OS信息

3.Services 当前正在工作的信息

4.Processes 当前执行的进程

(这里是可以管理远程和本地OS的)

好了,我们要开始实现访问我们的OS了,不过在这之前我们必须要引入System.Management

这个命名空间

下面让我们了解一下控件的状态事件

我们必须保证是实时的所以必须在这里包涵UpdateStatus(string e)该事件(这是一个自定义的)

这里主要是希望在点击每个控件时刷新状态栏,可以让用户知道程序在做什么!

代码事例:

//控件代码

//状态事件的代理

public delegate void Status(string e);

public event Status UpdateStatus;

//这里更新状态栏

UpdateStatus("Hello world.");

//这里是在主程序里的代码

//写具体的事件代码

private void refreshStatusBar(string stringStatus)

{

//update status bar

statusBarStatus.Text = stringStatus;

}

下面是具体代码:

Explorer Control

这里首先介绍一下WMI的 Win32_LogicalDisk类(参考Platform SDK: Windows Management Instrumentation),通过它我们可以查看到本地驱动器

的一些详细情况,我们还需要用到System.Management中的两个类ManagementObjectSearcher

和ManagementOjbectCollection它们的作用主要是ManagementObjectSearcher将查询到了

ManagementOjbectCollection该对象的集合中去(这里可以获取的驱动器信息包括 驱动器的名称

,类型,描述信息等)当然你也可以只查看驱动器的部分信息可以在ManagementObjectSearcher类

的构造函数中这样写ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * From Win32_LogicalDisk "); (参考Platform SDK: Windows Management Instrumentation)

代码如下:

//get drive collection

ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * From Win32_LogicalDisk ");

ManagementObjectCollection queryCollection = query.Get();

//loop throught each object to get drive information

foreach ( ManagementObject mo in queryCollection)

{

switch (int.Parse( mo["DriveType"].ToString()))

{

case Removable: //removable drives

imageIndex = 5;

selectIndex = 5;

break;

case LocalDisk: //Local drives

imageIndex = 6;

selectIndex = 6;

break;

case CD: //CD rom drives

imageIndex = 7;

selectIndex = 7;

break;

case Network: //Network drives

imageIndex = 8;

selectIndex = 8;

break;

default: //defalut to folder

imageIndex = 2;

selectIndex = 3;

break;

}

//get drive name

Console.WriteLine("Drive: " + mo["Name"].ToString());

}

SystemInfo Control

该控件主要用来查看本地或远程主机的OS和硬件信息,这里需要用到另外两个

对象ConnectionOptions和ManagementScope,ConnectionOptions主要是设置

WMI连接信息的,如用户名和密码,这里我们主要用到它的两个属性UserName和

Password; ManagementScope对象表示WMI的规范,通过该规范可以访问服务器

和命名空间的路径已及使用ConnectionOptions中的设置

请看如下代码:

//Connect to the remote computer

ConnectionOptions co = new ConnectionOptions();

co.Username = textUserID.Text;

co.Password = textPassword.Text;

//Point to machine

System.Management.ManagementScope ms = new System.Management.ManagementScope("\\\\" +

stringHostName + "\\root\\cimv2", co);

现在我们结合刚才的知识来得到我们要的信息,但我们要得到那些我们想要信息呢?

那样的话我们就必须要用到ObjectQuery对象,通过它我们可以得到我们想要的查询

信息.把ObjectQuery对象和ManagementScope对象放入ManagementObjectSearcher对象

中这样就可以通过我们设置好的规范和我们设置好的查询得到我们想要的结果,当然

还必须要掉用ManagementObjiectSearcher的Get()方法,它会返回一个ManagementObject

对象的集合,然后可以通过结合操作来访问到每一个我们要的信息.

代码如下:

//Query system for Operating System information

oq = new System.Management.ObjectQuery("SELECT * FROM Win32_OperatingSystem");

query = new ManagementObjectSearcher(ms,oq);

queryCollection = query.Get();

foreach ( ManagementObject mo in queryCollection)

{

//create child node for operating system

createChildNode(nodeCollection, "Operating System: " + mo["Caption"]);

createChildNode(nodeCollection, "Version: " + mo["Version"]);

createChildNode(nodeCollection, "Manufacturer : " + mo["Manufacturer"]);

createChildNode(nodeCollection, "Computer Name : " +mo["csname"]);

createChildNode(nodeCollection, "Windows Directory : " + mo["WindowsDirectory"]);

}

要是你只是希望查看到本地主机的信息,你就没必要去创建 ConnectionOption, ManagementScope,ObjectQuery 对象,你仅仅只需要把ManagementObjectSearcher

对象的结果在ManagementObjectCollection集合里去调用Get()方法既可.

代码如下:

ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * From Win32_OperatingSystem");

ManagementObjectCollection queryCollection = query.Get();

这里只是介绍了OS信息的方法,其它的如Bios,Memory.Network Connection等信息的查看

只需要把查询字改改就可以了!(可参考Platform SDK: Windows Management Instrumentation)

Service Control控件介绍:

该控件要用到一个新的查询字"SELECT * FROM Win32_Service",通过它我们就可以

得到系统中有那些服务存在.为了方便启动和终止一项服务我们可以在ListView中

动态的创建一个弹出式菜单,当用鼠标左击ListView中的Item的时候,可以用来启动

或终止一项服务.可以这样来指定你要的服务"SELECT * FROM Win32_Service WHERE

Name = 'ServiceName'",这个时候我们要调用ManagementObject.InvokeMethod()

来指定是终止还是启动一个服务.InvokeMethod()的第一个参数是一个ManagementBaseObject

的对象.它用作更具体的管理对象类的基类.我通过一个ManagementOperationObserver对象

管理异步操作和处理异步收到的管理信息和事件。可以由completionHandlerObj.ReturnObject

(为自定义类的属性)

属性返回值来判断是否成功.

代码如下:

///

/// List view mouse down event to built context menu dynamically

///

///

///

private void listViewServices_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)

{

System.Windows.Forms.ListView listViewObject = (System.Windows.Forms.ListView) sender;

ContextMenu mnuContextMenu = new ContextMenu();

MenuItem menuItem = new MenuItem();

ManagementObjectCollection queryCollection;

//check if right button

if (e.Button == System.Windows.Forms.MouseButtons.Right)

{

//get service name

ServiceName = listViewObject.GetItemAt(e.X, e.Y).Text;

//set list view item

ServiceItem = listViewObject.GetItemAt(e.X,e.Y);

//create popup menu

listViewObject.ContextMenu = mnuContextMenu;

try

{

//get specific service object

queryCollection = getServiceCollection("SELECT * FROM Win32_Service Where Name = '" +

ServiceName + "'");

foreach ( ManagementObject mo in queryCollection)

{

//create menu depending on service state

if (mo["Started"].Equals(true))

{

menuItem.Text = "Stop";

//set action property

ServiceAction = "StopService";

}

else

{

menuItem.Text = "Start";

ServiceAction = "StartService";

}

mnuContextMenu.MenuItems.Add(menuItem);

// Add functionality to the menu items using the Click event.

menuItem.Click += new System.EventHandler(this.menuItem_Click);

}

}

catch (Exception e1)

{

MessageBox.Show("Error: " + e1);

}

}

}

///

/// List view context menu click event to invoke start/stop service

///

///

///

private void menuItem_Click(object sender, System.EventArgs e)

{

ManagementObjectCollection queryCollection;

ListViewItem lvItem;

//Set up a handler for the asynchronous callback

ManagementOperationObserver observer = new ManagementOperationObserver();

completionHandler.MyHandler completionHandlerObj = new completionHandler.MyHandler();

observer.ObjectReady += new ObjectReadyEventHandler(completionHandlerObj.Done);

//get specific service object

queryCollection = getServiceCollection("Select * from Win32_Service Where Name ='" +

ServiceName + "'");

//Status

updateStatus("Starting/Stopping service...");

foreach ( ManagementObject mo in queryCollection)

{

//start or stop service

mo.InvokeMethod(observer, ServiceAction, null);

}

//wait until invoke method is complete or 5 sec timeout

int intCount = 0;

while

(!completionHandlerObj.IsComplete)

{

if

(intCount 10)

{

MessageBox.Show("Terminate process timed out.", "Terminate Process Status");

break;

}

//wait 1/2 sec.

System.Threading.Thread.Sleep(500);

//increment counter

intCount++;

}

//see if call was successful.

if (completionHandlerObj.ReturnObject.Properties["returnValue"].Value.ToString() == "0")

{

//succeeded

lvItem = ServiceItem;

if (ServiceAction == "StartService")

lvItem.SubItems[2].Text = "Started";

else

lvItem.SubItems[2].Text = "Stop";

}

else

{

//error message

string stringAction;

if (ServiceAction == "StartService")

stringAction = "start";

else

stringAction = "stop";

MessageBox.Show("Failed to " + stringAction + " service " + ServiceName + ".",

"Start/Stop Service Failure");

}

//clean-up objects

ServiceName = "";

ServiceAction = "";

ServiceItem = null;

//Status

updateStatus("Ready");

this.Update();

}

//----------------------------------

// Completion Handler

//----------------------------------

using System;

using System.Management;

namespace completionHandler

{

///

/// MyHandler class handle notification when InvokeMethod call is complete

///

public class MyHandler

{

private bool isComplete = false;

private ManagementBaseObject returnObject;

///

/// Trigger Done event when InvokeMethod is complete

///

public void Done(object sender, ObjectReadyEventArgs e)

{

isComplete = true;

returnObject = e.NewObject;

}

///

/// Get property IsComplete

///

public bool IsComplete

{

get

{

return isComplete;

}

}

///

/// Property allows accessing the result object in the main function

///

public ManagementBaseObject ReturnObject

{

get

{

return returnObject;

}

}

}

}

ProcessesControl控件介绍:

该控件主要用来显示系统中正在运行的进程,如:用户进程.CPU利用率,

内存的使用状况.我们可以通过GetOwner(User,Domain)方法来得知进程

的所有者是谁.User和Domain是入口参数,可是问题是我们如何从InvokeMethod

中得到这入口参数呢?这里我们需要实现InvokeMethod.一下讨论两种情况

1.我们不需要异步操作,我们仅仅只需要一个string[]数组就可以完成

2.当我们需要异步操作的时候也只需要一个completionHandlerObj.ReturnObject

属性来收集对象.

代码如下:

//-------------------------------------------------

//Get process owner info without the observer object

//--------------------------------------------------

//Createan array containing all arguments for the method

string[] methodArgs = {"", ""};

//Get process owner info

mo.InvokeMethod("GetOwner", methodArgs);

//methodArgs[0] - contain process user

//methodArgs[1] = contain process domain

//-----------------------------------------------

//Getprocess owner info with the observer object

//-----------------------------------------------

mo.InvokeMethod(observer,"GetOwner", null);

while (!completionHandlerObj.IsComplete)

{

System.Threading.Thread.Sleep(500);

}

if (completionHandlerObj.ReturnObject["returnValue"].ToString() == "0")

structProcess.stringUserName = completionHandlerObj.ReturnObject.Properties["User"].Value.ToString();

else

structProcess.stringUserName = "";

下面讨论如何终结进程:

终结一个指定的进程很类似与上面提到的启动或终止一项服务.

首先当然是用ManagementObject对象来指定你要的进程,然后调用

InvokeMethod(observer,"Terminate",null)来终止一个进程.

代码如下:

//Set up a handler for the asynchronous callback

ManagementOperationObserver observer = new ManagementOperationObserver();

completionHandler.MyHandler completionHandlerObj = new completionHandler.MyHandler();

observer.ObjectReady += new ObjectReadyEventHandler(completionHandlerObj.Done);

//Get ManagementObject for process

queryCollection = getProcessCollection("Select * from Win32_Process Where ProcessID = '" + ProcessID + "'");

//Status

updateStatus("Invoking terminate process");

foreach ( ManagementObject mo in queryCollection)

{

//start or stop service

mo.InvokeMethod(observer, "Terminate", null);

}

//wait until invoke method is complete or 5 sec timeout

int intCount = 0;

while (!completionHandlerObj.IsComplete)

{

if (intCount == 10)

{

MessageBox.Show("Terminate process timed out.", "Terminate Process Status");

break;

}

//wait 1/2 sec.

System.Threading.Thread.Sleep(500);

//increment counter

intCount++;

}

if (intCount != 10)

{

//InvokeMethod did not time out

if (completionHandlerObj.ReturnObject.Properties["returnValue"].Value.ToString() == "0")

{

lvItem = ProcessItem;

lvItem.Remove();

}

else

{

MessageBox.Show("Error terminating process.", "Terminate Process");

}

}

创建进程:

创建一个新的进程我们需要调用ManagementClass类的InvokeMethod方法来完成

我们可以通过ManagementClass processClass = New ManagementClass(ms,path,null);

这条语句来实现一个ManagementClass对象.ms是一个ManagementScope类的实例;

,path是一个ManagementPath的实例.ManagementScope来设置Management的范围.

ManagementPath用来提供一个包装,用于分析和生成 WMI 对象的路径.("Win32_Process")

在这之前我们还需要调用ManagementClass.InvokeMethod(observer, methodName, inParameters).

我们可以通过一个对象数组来一次传递四个参数.inParameters实际上就是一个

Create Method in Class Win32_Process(参考Platform SDK: Windows Management Instrumentation)

uint32 Create(string CommandLine,

string CurrentDirectory,

Win32_ProcessStartup ProcessStartupInformation,

uint32* ProcessId);

Parameters

CommandLine - [in] Command line to execute. The system adds a null character to the command line, trimming the string if necessary, to indicate which file was actually used.

CurrentDirectory - [in] Current drive and directory for the child process. The string requires that the current directory resolves to a known path. A user can specify an absolute path or a path relative to the current working directory. If this parameter is NULL, the new process will have the same path as the calling process. This option is provided primarily for shells that must start an application and specify the application's initial drive and working directory.

ProcessStartupInformation - [in] The startup configuration of a Windows process. For more information see Win32_ProcessStartup.

ProcessId - [out] Global process identifier that can be used to identify a process. The value is valid from the time the process is created until the time the process is terminated

例如代码:

//Create an array containing all arguments for the method

object[] methodArgs = {stringCommandLine, null, null, 0};

//Execute the method

processClass.InvokeMethod (observer, "Create", methodArgs);

下面的代码是用来创建并插入一个新的进程.我们可以写一个CreateProcess

函数通过参数stringCommandLine来传递一个你希望创建的进程.如你可以

这样写 CreateProcess("Calc.exe"), 这时候你就可以创建一个计算器

进程了,下面是个例子.

代码如下;

///

/// Invoke method 'Create' on local or remote machine

///

///

private void CreateProcess(string stringCommandLine)

{

//Set up a handler for the asynchronous callback

ManagementOperationObserver observer = new ManagementOperationObserver();

completionHandler.MyHandler completionHandlerObj = new completionHandler.MyHandler();

observer.ObjectReady += new ObjectReadyEventHandler(completionHandlerObj.Done);

string stringMachineName = "";

//Connect to the remote computer

ConnectionOptions co = new ConnectionOptions();

if (radioMachine.Checked == true)

{

stringMachineName = "localhost";

}

else

{

stringMachineName = textIP.Text;

}

if (stringMachineName.Trim().Length == 0)

{

MessageBox.Show("Must enter machine IP address or name.");

return;

}

//get user and password

if (textUserID.Text.Trim().Length 0)

{

co.Username = textUserID.Text;

co.Password = textPassword.Text;

}

//Point to machine

System.Management.ManagementScope ms = new System.Management.ManagementScope("\\\\" +

stringMachineName + "\\root\\cimv2", co);

//get process path

ManagementPath path = new ManagementPath( "Win32_Process");

//Get the object on which the method will be invoked

ManagementClass processClass = new ManagementClass(ms,path,null);

//Status

updateStatus("Create process " + stringCommandLine + ".");

//Create an array containing all arguments for the method

object[] methodArgs = {stringCommandLine, null, null, 0};

//Execute the method

processClass.InvokeMethod (observer, "Create", methodArgs);

//wait until invoke method is complete or 5 sec timeout

int intCount = 0;

while (!completionHandlerObj.IsComplete)

{

if (intCount 10)

{

MessageBox.Show("Create process timed out.", "Terminate Process Status");

break;

}

//wait 1/2 sec.

System.Threading.Thread.Sleep(500);

//increment counter

intCount++;

}

if (intCount != 10)

{

//InvokeMethod did not time out

//check for error

if (completionHandlerObj.ReturnObject.Properties["returnValue"].Value.ToString() == "0")

{

//refresh process list

this.Refresh();

}

else

{

MessageBox.Show("Error creating new process.", "Create New Process");

}

}

//Status

updateStatus("Ready");

this.Update();

}

总结:

这里只是做了一个使用WMI的例子.我们大体可以通过这个简单的例子

了解一下WMI究竟可以做那些事情.我想,我在代码中的注释可以很方便

让大家了解WMI.

下面这个列表可以让你明白WMI能处理那些问题:

*控制你的软硬件

*监管事件

*执行一个基于事件的描述

*通过事件来发送E-mail

参考资料:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/wmi_start_page.asp

http://www.microsoft.com/taiwan/technet/scriptcenter/sampscr.htm

作者Blog:http://blog.csdn.net/yarshray/

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有