本文比较全面地介绍了WMI的使用方法和技巧,特此推荐。 
 
很多的朋友对 WMI 可能见过但理解不深,我也是十分想了解关于 WMI 的知识,可一直找不对太合适的资料,在网上的一些资料不是有很多错误,就是讲解不清,我有空的时候将关于 WMI 的知识集中一下,放在这里便于大家学习。本贴会不断增加。
1   什么是 WMI
WMI 是英文 Windows Management Instrumentation 的简写,它的功能主要是:访问本地主机的一些信息和服务,可以管理远程计算机(当然你必须要拥有足够的权限),比如:重启,关机,关闭进程,创建进程等。
2   如何用 WMI 获得本地磁盘的信息?
首先要在 VS.NET 中创建一个项目,然后在添加引用中引用一个 .net 的装配件:
System.Management.dll, 这样你的项目才能使用 WMI 。代码如下:
using System;
using System.Management;
class Sample_ManagementObject
{
 public static int Main(string[] args) 
 {
  SelectQuery query=new SelectQuery("Select * From Win32_LogicalDisk");
  ManagementObjectSearcher searcher=new ManagementObjectSearcher(query);
  foreach(ManagementBaseObject disk in searcher.Get())
  {
   Console.WriteLine("\r\n"+disk["Name"] +" "+disk["DriveType"] + " " + disk["VolumeName"]);
  }
  Console.ReadLine();
  return 0;
 }
}
disk["DriveType"]  的返回值意义如下 :
1 No type 
2 Floppy disk 
3 Hard disk 
4 Removable drive or network drive 
5 CD-ROM 
6 RAM disk
 
3 、如何用 WMI 获得指定磁盘的容量?
using System;
using System.Management;
// This example demonstrates reading a property of a ManagementObject.
class Sample_ManagementObject
{
 public static int Main(string[] args) 
 {
  ManagementObject disk = new ManagementObject(
   "win32_logicaldisk.deviceid=\"c:\"");
  disk.Get();
  Console.WriteLine("Logical Disk Size = " + disk["Size"] + " bytes");
  Console.ReadLine(); 
  return 0;
 }
}
4   如何列出机器中所有的共享资源?
using System;
using System.Management;
class TestApp {
 [STAThread]
 static void Main()
 {
  ManagementObjectSearcher searcher = new ManagementObjectSearcher(
   "SELECT * FROM Win32_share");
  foreach (ManagementObject share in searcher.Get())
  {
   Console.WriteLine(share.GetText(TextFormat.Mof));
  }
 }
}
别忘记在引用中把 System.Management 添加进来。
5   怎样写程控制让系统中的某个文件夹共享或取消共享 .
首先,这需要以有相应权限的用户登录系统才行。然后,试试下面的代码:
using System;
using System.Management;
class CreateShare
{
 public static void Main(string[] args)
 {
  ManagementClass _class = new ManagementClass(new ManagementPath("Win32_Share"));
  object[] obj = {"C:\\Temp"," 我的共享 ",0,10,"Dot Net  实现的共享 ",""};
  _class.InvokeMethod("create",obj);
 }
}
object[] obj = {"C:\\Temp"," 我的共享 ",0,10,"Dot Net  实现的共享 ",""};
改为
object[] obj = {"C:\\Temp"," 我的共享 ",0,null,"Dot Net  实现的共享 ",""};
就可以实现授权给最多用户了。
6   如何获得系统服务的运行状态?
private void getServices()
{
 ManagementObjectCollection queryCollection;
 string[] lvData =  new string[4];
 try
 {
  queryCollection = getServiceCollection("SELECT * FROM Win32_Service");
  foreach ( ManagementObject mo in queryCollection)
  {
   //create child node for operating system
   lvData[0] = mo["Name"].ToString();
   lvData[1] = mo["StartMode"].ToString();
   if (mo["Started"].Equals(true))
    lvData[2] = "Started";
   else
    lvData[2] = "Stop";
    lvData[3] = mo["StartName"].ToString();
     
    //create list item
    ListViewItem lvItem = new ListViewItem(lvData,0);
    listViewServices.Items.Add(lvItem);
  }
 }
 catch (Exception e)
 {
  MessageBox.Show("Error: " + e);
 }
}
7   通过 WMI 修改 IP ,而实现不用重新启动?
using System;
using System.Management;
using System.Threading;
namespace WmiIpChanger
{
 class IpChanger
 {
  [MTAThread]
  static void Main(string[] args)
  {
   ReportIP();
   // SwitchToDHCP();
   SwitchToStatic();
   Thread.Sleep( 5000 );
   ReportIP();
   Console.WriteLine( "end." );
  }
  static void SwitchToDHCP()
  {
   ManagementBaseObject inPar = null;
   ManagementBaseObject outPar = null;
   ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
   ManagementObjectCollection moc = mc.GetInstances();
   foreach( ManagementObject mo in moc )
   {
    if( ! (bool) mo["IPEnabled"] )
     continue;
    inPar = mo.GetMethodParameters("EnableDHCP");
    outPar = mo.InvokeMethod( "EnableDHCP", inPar, null );
    break;
   }
  }
  static void SwitchToStatic()
  {
   ManagementBaseObject inPar = null;
   ManagementBaseObject outPar = null;
   ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
   ManagementObjectCollection moc = mc.GetInstances();
   foreach( ManagementObject mo in moc )
   {
    if( ! (bool) mo[ "IPEnabled" ] )
     continue;
    inPar = mo.GetMethodParameters( "EnableStatic" );
    inPar["IPAddress"] = new string[] { "192.168.1.1" };
    inPar["SubnetMask"] = new string[] { "255.255.255.0" };
    outPar = mo.InvokeMethod( "EnableStatic", inPar, null );
    break;
   }
  }
  static void ReportIP()
  {
   Console.WriteLine( "****** Current IP addresses:" );
   ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
   ManagementObjectCollection moc = mc.GetInstances();
   foreach( ManagementObject mo in moc )
   {
    if( ! (bool) mo[ "IPEnabled" ] )
     continue;
    Console.WriteLine( "{0}\n SVC: '{1}' MAC: [{2}]", (string) mo["Caption"],
     (string) mo["ServiceName"], (string) mo["MACAddress"] );
    string[] addresses = (string[]) mo[ "IPAddress" ];
    string[] subnets = (string[]) mo[ "IPSubnet" ];
    Console.WriteLine( " Addresses :" );
    foreach(string sad in addresses)
     Console.WriteLine( "\t'{0}'", sad );
    Console.WriteLine( " Subnets :" );
    foreach(string sub in subnets )
     Console.WriteLine( "\t'{0}'", sub );
   }
  }
 }
}
8   如何利用 WMI 远程重启远程计算机?
using System;
using System.Management;  
namespace WMI3
{
      /// 
      /// Summary description for Class1.
      /// 
 
      class Class1
      {
            static void Main(string[] args)
            {
                  Console.WriteLine("Computer details retrieved using Windows Management Instrumentation (WMI)");
                  Console.WriteLine("mailto:Written%<st1:chsdate w:st="on" IsROCDate="False" IsLunarDate="False" Day="2" Month="1" Year="2002">2002/01/02%20By%20John%20O'Donnell%20-%[email][email protected][/email]");
                  Console.WriteLine("========================================
================================="); 
                   //
连接远程计算机
            ConnectionOptions co = new ConnectionOptions();
            co.Username = "john";
            co.Password = "john";
            System.Management.ManagementScope ms = new System.Management.ManagementScope("\\\\192.168.1.2\\root\\cimv2", co);      
                  //
查询远程计算机
           System.Management.ObjectQuery oq = new System.Management.ObjectQuery("SELECT * FROM Win32_OperatingSystem");
                  
           ManagementObjectSearcher query1 = new ManagementObjectSearcher(ms,oq);
           ManagementObjectCollection queryCollection1 = query1.Get();            
                  foreach( ManagementObject mo in queryCollection1 ) 
                  {
                        string[] ss={""};
                        mo.InvokeMethod("Reboot",ss);
                        Console.WriteLine(mo.ToString());
                  }
            }
      }
}  
9   利用 WMI 创建一个新的进程?
using System;
using System.Management;
// This sample demonstrates invoking a WMI method using parameter objects
public class InvokeMethod 
{    
 public static void Main() 
 {
  //Get the object on which the method will be invoked
  ManagementClass processClass = new ManagementClass("Win32_Process");
  //Get an input parameters object for this method
  ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
  //Fill in input parameter values
  inParams["CommandLine"] = "calc.exe";
  //Execute the method
  ManagementBaseObject outParams = processClass.InvokeMethod ("Create", inParams, null);
  //Display results
  //Note: The return code of the method is provided in the "returnvalue" property of the outParams object
  Console.WriteLine("Creation of calculator process returned: " + outParams["returnvalue"]);
  Console.WriteLine("Process ID: " + outParams["processId"]);
 }
}
10   如何通过 WMI 终止一个进程?
using System; 
using System.Management; 
// This example demonstrates how to stop a system service. 
class Sample_InvokeMethodOptions 

    public static int Main(string[] args) {
        ManagementObject service = 
            new ManagementObject("win32_service=\"winmgmt\"");
        InvokeMethodOptions options = new InvokeMethodOptions();
        options.Timeout = new TimeSpan(0,0,0,5); 
        ManagementBaseObject outParams = service.InvokeMethod("StopService", null, options);
        Console.WriteLine("Return Status = " + outParams["Returnvalue"]);
        return 0;
    }
}
11   如何用 WMI  来获取远程机器的目录以及文件 . 比如如何列出一个目录下的所有文件 , 或者所有子目录 ; 如何删除 , 舔加 , 更改文件 ?
using System;
using System.Management;
// This example demonstrates reading a property of a ManagementObject.
            class Sample_ManagementObject
            {
                public static int Main(string[] args) {
                    ManagementObject disk = new ManagementObject(
                        "win32_logicaldisk.deviceid=\"c:\"");
                    disk.Get();
                    Console.WriteLine("Logical Disk Size = " + disk["Size"] + " bytes");
                    return 0;
                }
            }

12
  参考资料
可以参考下列内容:
msdn WMI SDK:
[url]http://msdn.microsoft.com/library/default.asp?url=/library/en-[/url]us/wmisdk/wmi/wmi_start_page.asp
WMI 使用说明( csdn:
[url]http://www.csdn.net/develop/article/15/15346.shtm[/url]
WMI 技术的应用  for .netcsdn:
[url]http://www.csdn.net/develop/article/16/16419.shtm[/url]
.NET 中轻松获取系统信息 (1) WMI 篇( csdn:
[url]http://www.csdn.net/develop/article/15/15744.shtm[/url]

 :)

13
  一些技巧
我使用 WMI 可以取出网卡的 MAC 地址, CPU 的系列号,主板的系列号,其中主板的系列号已经核对过没有错的,其余的有待于验证,因为我使用的是笔记本,笔记本背面有一个主板的系列号,所以可以肯定主板系列号没有问题
网卡的 MAC 地址
SELECT MACAddress FROM Win32_NetworkAdapter WHERE ((MACAddress Is Not NULL) AND (Manufacturer <> 'Microsoft'))
结果: 08:00:46:63:FF:8C

CPU
的系列号
Select ProcessorId From Win32_Processor
结果: 3FEBF9FF00000F24

主板的系列号
Select SerialNumber From Win32_BIOS
结果: 28362630-3700521
获取硬盘 ID
String HDid;
ManagementClass cimobject = new ManagementClass("Win32_DiskDrive");
ManagementObjectCollection moc = cimobject.GetInstances();
foreach(ManagementObject mo in moc)
{
 HDid = (string)mo.Properties["Model"].value;
 MessageBox.Show(HDid  ); 
}

14
  一个使用 WMI 后的异常处理的问题
下面是我整理的一段代码 .
 
 ManagementObjectCollection queryCollection1;
  ConnectionOptions co = new ConnectionOptions();
  co.Username = "administrator";
  co.Password = "111";
  try
  {
   System.Management.ManagementScope ms = new System.Management.ManagementScope(@"\\csnt3\root\cimv2", co);
   System.Management.ObjectQuery oq = new System.Management.ObjectQuery("SELECT * FROM Win32_OperatingSystem");
   ManagementObjectSearcher query1 = new ManagementObjectSearcher(ms,oq);
   queryCollection1 = query1.Get();
   foreach( ManagementObject mo in queryCollection1 )
   {
    string[] ss={""};
    mo.InvokeMethod("Reboot",ss);
    Console.WriteLine(mo.ToString());
   }
  }
  catch(Exception ee)
  {
   Console.WriteLine("error");
  }

15
Windows  管理规范  (WMI)  是可伸缩的系统管理结构,它采用一个统一的、基于标准的、可扩展的面向对象接口。 WMI  为您提供与系统管理信息和基础  WMI API  交互的标准方法。 WMI  主要由系统管理应用程序开发人员和管理员用来访问和操作系统管理信息。
WMI 
可用于生成组织和管理系统信息的工具,使管理员或系统管理人员能够更密切地监视系统活动。例如,可以使用  WMI  开发一个应用程序,用于在  Web  服务器崩溃时呼叫管理员。
 WMI  .NET  框架一起使用
WMI 
提供了大量的规范以便为许多高端应用程序(例如, Microsoft ExchangeMicrosoft SQL Server  Microsoft Internet  信息服务  (IIS) )实现几乎任何管理任务。管理员可以执行下列任务:  
监视应用程序的运行状况。  
检测瓶颈或故障。  
管理和配置应用程序。  
查询应用程序数据(使用对象关系的遍历和查询)。  
执行无缝的本地或远程管理操作。  
WMI 
结构由以下三层组成:  
客户端  
使用  WMI  执行操作(例如,读取管理详细信息、配置系统和预订事件)的软件组件。  
对象管理器  
提供程序与客户端之间的中间装置,它提供一些关键服务,如标准事件发布和预订、事件筛选、查询引擎等。  
提供程序  
软件组件,它们捕获实时数据并将其返回到客户端应用程序,处理来自客户端的方法调用并将客户端链接到所管理的基础结构。  
通过定义完善的架构向客户端和应用程序无缝地提供了数据和事件以及配置系统的能力。在  .NET  框架中, System.Management  命名空间提供了用于遍历  WMI  架构的公共类。
除了  .NET  框架,还需要在计算机上安装  WMI  才能使用该命名空间中的管理功能。如果使用的是  Windows Millennium EditionWindows 2000  Windows XP ,那么已经安装了  WMI 。否则,将需要从  MSDN  下载  WMI
 System.Management  访问管理信息
System.Management 
命名空间是  .NET  框架中的  WMI  命名空间。此命名空间包括下列支持  WMI  操作的第一级类对象:  
? ManagementObject 
 ManagementClass :分别为单个管理对象或类。  
? ManagementObjectSearcher
:用于根据指定的查询或枚举检索  ManagementObject  ManagementClass  对象的集合。  
? ManagementEventWatcher
:用于预订来自  WMI  的事件通知。  
? ManagementQuery
:用作所有查询类的基础。  
System.Management 
类的使用编码范例对  .NET  框架环境很适合,并且  WMI  在任何适当的时候均使用标准基框架。例如, WMI  广泛利用  .NET  集合类并使用推荐的编码模式,如  .NET  异步操作的 委托 模式。因此,使用  .NET  框架的开发人员可以使用他们的当前技能访问有关计算机或应用程序的管理信息。
请参见
使用  WMI  管理应用程序  |  检索管理对象的集合  |  查询管理信息  |  预订和使用管理事件  |  执行管理对象的方法  |  远程处理和连接选项  |  使用强类型对象
 
获取 CPU 序列号代码
string cpuInfo = "";//cpu
序列号
   ManagementClass cimobject = new ManagementClass("Win32_Processor");
   ManagementObjectCollection moc = cimobject.GetInstances();
   foreach(ManagementObject mo in moc)
   {
    cpuInfo = mo.Properties["ProcessorId"].value.ToString();
    Console.WriteLine(cpuInfo);
    Console.ReadLine();
   }
获取网卡硬件地址
using System.Management;
...
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach(ManagementObject mo in moc)
{
if((bool)mo["IPEnabled"] == true)
Console.WriteLine("MAC address\t{0}", mo["MacAddress"].ToString());
mo.Dispose();
}
}
获取硬盘 ID
String HDid;
ManagementClass cimobject = new ManagementClass("Win32_DiskDrive");
ManagementObjectCollection moc = cimobject.GetInstances();
foreach(ManagementObject mo in moc)
{
 HDid = (string)mo.Properties["Model"].value;
 MessageBox.Show(HDid  ); 
}

16
、在 .NET 中轻松获取系统信息 (1)  WMI
Montaque

申明:
    1
、个人的一点心得,仅供参考
    2
、转载时候,请保留原本。
概述:
 
不知道大家有没有这种体会?有时候为了获取系统一点点信息,比如考虑一下操作系统的版本号,或者当前屏幕的分辨率。其实说到底就是读操作系统某个方面的一个属性值而已,然后就看到我们的程序中密密麻麻的 Win32 API 申明,调用,代码的可读性和维护性不言而喻。到了 .NET ,微软提供了更为丰富的类,有很多以前要调用 API 的方法可以在 .NET 中轻而易举的调用实现。今天简单介绍一个在 .NET 中如何通过与 WMIWindows  管理规范)的通讯,从而得到获取信息的目的。
主要思路:
 
举一个获取操作系统共享目录和获取主板号的例子,介绍如何利用 System.Managment 下面的类获取系统相关的信息:
正文:
 WMI
Windows 管理规范: Windows Management Instrumentation )是 Microsoft 基于 Web 的企业管理( WBEM )的实现,同时也是一种基于标准的系统管理接口。 WMI 最早出现在 Microsoft Windows 2000 系统上,但它同样可以安装在 Windows NT 4Windows 9x 计算机上。 WMI 是一种轻松获取系统信息的强大工具。
 
.NET 中,有一个 System.Management 名空间(系统默认没有引用,我们可以手动添加引用),通过下面的 Class 的操作,可以查询系统软硬件的信息,先看一个简单的例子:
Imports System.Management
Dim searcher As New ManagementObjectSearcher("SELECT * FROM Win32_share")
Dim share As ManagementObject
 For Each share In searcher.Get()
       MessageBox.Show(share.GetText(TextFormat.Mof))
 Next share
运行的结果是列出了所有系统当前共享的目录、以及描述等等。
分析一下上面的代码,可以看到一下几点:
1
、似乎是在进行数据库操作,有点像 SQL 语句。其实就是 SQL 操作,这种语句被成 WQL(WMI Query Language) ,实际上是标准 SQL 的一个子集加上了 WMI 的扩展 .
2
WQL 是个只读的查询语言,我们只能查询响应的数据,不能用 UPDATE,INSERT 等更新操作
3
、代码很简单、通俗易懂
4
、我们采用了一种 MOF (托管对象格式)的显示。
例子二:获取当前主板的信息
 
上面的例子是一个软件方面的信息,下面看一个获取硬件信息的例子,获取主板的序列号以及制造商:
Dim searcher As New ManagementObjectSearcher("SELECT * FROM Win32_BaseBoard")
Dim share As ManagementObject
   For Each share In searcher.Get()
      Debug.WriteLine("
主板制造商 :" & share("Manufacturer"))
      Debug.WriteLine("
型号 :" & share("Product"))
      Debug.WriteLine("
序列号 :" & share("SerialNumber"))
   Next share
总结以及补充:
 WMI
类也是分层次的,具体可以参考 msdn 中的 WMI ;转向 .NET 平台开发的时候,最好能多看一些关于 .NET 新特性的介绍,这样可以大幅度的提升代码的开发效率以及运行效率。