WMI介紹及簡單應用

http://blog.csdn.net/zhoufoxcn/archive/2008/01/14/2042697.aspx

 

前言: 由於.net的某些特點使它脫離了操作系統底層,所以如果我們想獲得一些底層的操作系統信息的時候比較困難,經常需要DllImport技術,這對一些對C/C++不熟悉的程序員來說簡直是一個夢魘(對於我來說也是如此,雖然大學裏學習過C/C++,可是我從來沒有用過它們做過任何實際的應用程序開發),所以能通過一些簡單的辦法處理的,我都繞過去了,很多時候我喜歡藉助命令行來執行一些命令,然後截取輸出流,處理之後返回我需要的結果,這個也是比較痛苦的。經常訪問我的博客的朋友應該對我的一篇文章很熟悉,或者從別的地方看到過,因爲它被衆多網站轉載了,這篇文章就是《用C#獲取CPU編號、硬盤編號等系統有關環境、屬性》,網址是:http://blog.csdn.net/zhoufoxcn/archive/2007/03/20/1534949.aspx

其實,還有一個爲大家所陌生、但功能卻又十分強大的工具,它就是WMI。WMI(Windows管理規範:Windows Management Instrumentation)是Microsoft基於Web的企業管理(WBEM)的實現,同時也是一種基於標準的系統管理接口。WMI最早出現在Microsoft Windows 2000系統上,但它同樣可以安裝在Windows NT 4和Windows 9x計算機上。WMI是一種輕鬆獲取系統信息的強大工具。利用它但是由於缺少WMI的介紹資料和學習資料(特別是中文的,因爲國內大部分程序員的E文水平都比較湊合,呵呵,本人也是相當湊合),所以知道WMI的不多,能運用的就少之又少了。

在WMI中有一種查詢語言,類似於SQL語言,這種語言叫做WQL(WMI Query Language),實際上是標準SQL的一個子集加上了WMI的擴展。在接下來的教程中我會給大家演示一些WQL的例子。

用js或者vbs都可以通過WMI來獲取系統信息。下面是一個用vbs編寫的獲取系統序列號的小程序,你可以把它複製到一個文本文件裏,然後保存爲文件爲.vbs的文件,然後運行:

Set SNSet = GetObject("winmgmts:").InstancesOf ("Win32_OperatingSystem")

for each SN in SNSet

 
MsgBox "當前操作系統的序列號是: " & SN.SerialNumber

next

這是在我的機子上運行的結果:

如果通過常規手段在.net裏讓你寫這個方法不知道你需要多少行代碼?需要利用幾次搜索引擎?一會我將展示如何在.net裏利用WMI獲取操作系統序列號。

其實在.net裏是支持WMI編程的,在.net類庫裏專門有一個System.Management 命名空間,MSDN介紹這個命名空間如下:
“提供對大量管理信息和管理事件集合的訪問,這些信息和事件是與根據 Windows 管理規範 (WMI) 結構對系統、設備和應用程序設置檢測點有關的。應用程序和服務可以使用從 ManagementObjectSearcher 和 ManagementQuery 派生的類,查詢感興趣的管理信息(例如在磁盤上還剩多少可用空間、當前 CPU 利用率是多少、某一應用程序正連接到哪一數據庫等等);或者應用程序和服務可以使用 ManagementEventWatcher 類預訂各種管理事件。這些可訪問的數據可以來自分佈式環境中託管的和非託管的組件。”。

System.Management 命名空間包含了下面一些常用類:
◆ManagementObject 或 ManagementClass:分別爲單個管理對象或類。  
◆ManagementObjectSearcher:用於根據指定的查詢或枚舉檢索 ManagementObject 或 ManagementClass 對象的集合。  
◆ManagementEventWatcher:用於預訂來自 WMI 的事件通知。  
◆ManagementQuery:用作所有查詢類的基礎。

在實際編程中需要注意,System.Management 命名空間中的類都存在於System.Management .dll這個文件中,所以在編程的時候一定要添加對這個dll文件的引用,如下圖:

然後還需要在我們的程序開始處添加如下代碼:System.Management,這樣我們採用使用這個命名空間下的類來進行WMI編程。

下面我將用一個方法展示我剛纔提到的如何在.net裏獲取操作系統序列號:

        /// <summary>
        
/// 獲取操作系統序列號
        
/// </summary>
        
/// <returns></returns>
        public string GetSerialNumber()
        {
            
string result = "";
            ManagementClass mClass 
= new ManagementClass("Win32_OperatingSystem");
            ManagementObjectCollection moCollection 
= mClass.GetInstances();
            
foreach (ManagementObject mObject in moCollection)
            {
                result 
+= mObject["SerialNumber"].ToString();
            }
            
return result;
        }

我想這個方法夠簡單的了。

下面貼出一些常用的方法來獲取系統相關的信息,代碼如下:

using System;
using System.Collections.Generic;
using System.Text;

namespace WMIDemo
{
    
/// <summary>
    
/// 說明:這個類很簡單,主要包含一個Main方法
    
/// 作者:周公
    
/// 日期:2008-1-14
    
/// 首發地址:http://blog.csdn.net/zhoufoxcn
    
/// </summary>
    class Program
    {
        
static void Main(string[] args)
        {
            GetSystemInfo getInfo 
= new GetSystemInfo();
            Console.WriteLine(
"序列號="+getInfo.GetSerialNumber());
            Console.WriteLine(
"CPU編號=" + getInfo.GetCpuID());
            Console.WriteLine(
"硬盤編號=" + getInfo.GetMainHardDiskId());
            Console.WriteLine(
"主板編號=" + getInfo.GetMainBoardId());
            Console.WriteLine(
"網卡編號=" + getInfo.GetNetworkAdapterId());
            Console.WriteLine(
"用戶組=" + getInfo.GetGroupName());
            Console.WriteLine(
"驅動器情況=" + getInfo.GetDriverInfo());
            Console.ReadLine();
        }
    }
}
由於是一個命令行程序,所以有上面那個類,下面這個類才包含我要展示的代碼:
using System;
using System.Collections.Generic;
using System.Text;
using System.Management;

namespace WMIDemo
{
    
/// <summary>
    
/// 說明:這個類主要用來展示如何利用WMI來獲取一些操作系統的信息
    
/// 作者:周公
    
/// 時間:2008-1-14
    
/// 首發地址:http://blog.csdn.net/zhoufoxcn
    
/// </summary>
    public class GetSystemInfo
    {
        
/// <summary>
        
/// 獲取操作系統序列號
        
/// </summary>
        
/// <returns></returns>
        public string GetSerialNumber()
        {
            
string result = "";
            ManagementClass mClass 
= new ManagementClass("Win32_OperatingSystem");
            ManagementObjectCollection moCollection 
= mClass.GetInstances();
            
foreach (ManagementObject mObject in moCollection)
            {
                result 
+= mObject["SerialNumber"].ToString() + " ";
            }
            
return result;
        }
        
/// <summary>
        
/// 查詢CPU編號
        
/// </summary>
        
/// <returns></returns>
        public string GetCpuID()
        {
            
string result = "";
            ManagementClass mClass 
= new ManagementClass("Win32_Processor");
            ManagementObjectCollection moCollection 
= mClass.GetInstances();
            
foreach (ManagementObject mObject in moCollection)
            {
                result 
+= mObject["ProcessorId"].ToString() + " ";
            }
            
return result;
        }
        
/// <summary>
        
/// 查詢硬盤編號
        
/// </summary>
        
/// <returns></returns>
        public string GetMainHardDiskId()
        {
            
string result = "";
            ManagementObjectSearcher searcher 
= new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
            ManagementObjectCollection moCollection 
= searcher.Get();
            
foreach (ManagementObject mObject in moCollection)
            {
                result 
+= mObject["SerialNumber"].ToString() + " ";
            }
            
return result;
        }

        
/// <summary>
        
/// 主板編號
        
/// </summary>
        
/// <returns></returns>
        public string GetMainBoardId()
        {
            
string result = "";
            ManagementObjectSearcher searcher 
= new ManagementObjectSearcher("root/CIMV2",
                    
"SELECT * FROM Win32_BaseBoard");
            ManagementObjectCollection moCollection 
= searcher.Get();
            
foreach (ManagementObject mObject in moCollection)
            {
                result 
+= mObject["SerialNumber"].ToString() + " ";
            }
            
return result;
        }

        
/// <summary>
        
/// 主板編號
        
/// </summary>
        
/// <returns></returns>
        public string GetNetworkAdapterId()
        {
            
string result = "";
            ManagementObjectSearcher searcher 
= new ManagementObjectSearcher("SELECT MACAddress FROM Win32_NetworkAdapter WHERE ((MACAddress Is Not NULL)AND (Manufacturer <> 'Microsoft'))");
            ManagementObjectCollection moCollection 
= searcher.Get();
            
foreach (ManagementObject mObject in moCollection)
            {
                result 
+= mObject["MACAddress"].ToString() + " ";
            }
            
return result;
        }

        
/// <summary>
        
/// 主板編號
        
/// </summary>
        
/// <returns></returns>
        public string GetGroupName()
        {
            
string result = "";
            ManagementObjectSearcher searcher 
= new ManagementObjectSearcher("root/CIMV2""SELECT * FROM Win32_Group");
            ManagementObjectCollection moCollection 
= searcher.Get();
            
foreach (ManagementObject mObject in moCollection)
            {
                result 
+= mObject["Name"].ToString() + " ";
            }
            
return result;
        }

        
/// <summary>
        
/// 獲取本地驅動器信息
        
/// </summary>
        
/// <returns></returns>
        public string GetDriverInfo()
        {
            
string result = "";
            ManagementObjectSearcher searcher 
= new ManagementObjectSearcher("root/CIMV2""SELECT * FROM Win32_LogicalDisk");
            ManagementObjectCollection moCollection 
= searcher.Get();
            
foreach (ManagementObject mObject in moCollection)
            {
                
//mObject["DriveType"]共有6中可能值,分別代表如下意義:
                
//1:No type   2:Floppy disk   3:Hard disk
                
//4:Removable drive or network drive   5:CD-ROM   6:RAM disk
                
//本處只列出固定驅動器(硬盤分區)的情況
                if (mObject["DriveType"].ToString() == "3")
                {
                    result 
+= string.Format("Name={0},FileSystem={1},Size={2},FreeSpace={3} ", mObject["Name"].ToString(),
                        mObject[
"FileSystem"].ToString(), mObject["Size"].ToString(), mObject["FreeSpace"].ToString());
                }
            }
            
return result;
        }
    }
}

程序的運行結果如下(不同機器上的結果會不相同):

最後說明:雖然絕大部分Windows操作系統已經安裝了WMI(根據微軟官方說法是自WinME以後的Windows系統包括WinME都安裝了),但是不能保證上面的代碼能在所有的Windows操作系統之上,如Win95之類,如果在不支持WMI的Windows系統上運行WMI,那麼需要從MSDN下載WMI。

另外,運行WMI需要當前Windows登錄用戶有一定的權限,由於本人開發時是以管理員的身份登錄並運行程序的,所以沒有權限異常提示,但是我不保證代碼在你處運行也正常,特別是在WebForm的環境下,因爲asp.net程序默認是較低的權限運行的(安全原因)。

請看下一篇《.net中的WMI編程(二):WMI中的WQL語言和WQL的測試工具》:http://blog.csdn.net/zhoufoxcn/archive/2008/01/14/2044246.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章