用C#和WMI擷取邏輯磁碟機詳細資料

來源:互聯網
上載者:User
用C#和WMI擷取邏輯磁碟機詳細資料作者:竇瑞欣 出處:天極開發 責任編輯: 方舟
在編寫某些Windows管理應用程式時,能夠從自訂的磁碟機挑選清單框中進行選擇無疑是非常專業的,使用Delphi或者C++的早期版本時我們都必須使用Win32所提供的許多關於擷取磁碟資訊的API函數來分別擷取像卷標、序號以及剩餘空間等資訊,現在我們將使用.Net架構和WMI(Windows Management Instrumentation - Windows 管理規範 )來實現上述功能。

  一、 簡介

  若僅簡單擷取邏輯磁碟機的名稱列表我們使用.Net架構的Environment.GetLogicalDrives即可,但是若想獲得更多關於磁碟機的資訊我們可以使用.Net架構下的System.Management 命名空間所提供的類和委託等對大量管理資訊和管理事件的集合進行訪問,這些資訊和事件都與 WMI有關,該命名空間下的類實際上也是對WMI的一種封裝,應用程式和服務可以使用從 ManagementObjectSearcher 和 ManagementQuery 派生的類,查詢感興趣的管理資訊,例如在磁碟上還剩多少可用空間、當前 CPU 利用率是多少、某一應用程式正串連到哪一資料庫等等,現在我們就以 C# 語言編寫擷取詳細的邏輯磁碟機資訊的樣本來展示.Net架構System.Management 命名空間的相關類和WMI編程,如:

  二、技術要點

  WMI最初是內建在 Windows 2000、Windows XP 和 Windows Server 2003 系列作業系統中核心的管理支援技術,目前WMI 已經是一種規範和基礎結構,通過它可以訪問、配置、管理和監視幾乎所有的 Windows 資源例如磁碟、事件記錄、檔案、檔案夾、檔案系統、網路組件、作業系統設定、效能資料、印表機、進程、註冊表設定、安全性、服務、共用、使用者、組等等。在 WMI 之前,能夠以編程方式訪問 Windows 資源的惟一方法就是通過 Win32 API,現在我們除了使用WMI 指令碼管理任何通過 WMI 公開的 Windows 資源外,還可以通過.Net架構對於WMI封裝的System.Management 命名空間來輕鬆實現。

  我們首先使用WMI查詢來擷取特定類名的SelectQuery執行個體,可以有兩種方法建立該執行個體,一是可以傳遞一個已知的類名,譬如本文需要傳遞的類名為:Win32_LogicalDisk,代碼如下:

SelectQuery selectQuery = new SelectQuery("win32_logicaldisk");

  或者使用wql查詢來建立查詢類的執行個體,代碼如下:

SelectQuery selectQuery = new SelectQuery("select * from win32_logicaldisk");

  或者只擷取類的部分屬性,代碼如下:

SelectQuery selectQuery = new SelectQuery("select Name,DriveType from win32_logicaldisk");

  WQL查詢語言是 SQL 的一個子集,查詢通過包含以下內容限制返回的資料量1、SELECT 子句,指定只返回某些屬性的資料;2、WHERE 子句,指定要返回的執行個體。Win32_LogicalDisk類在預設的本地MSDN裡是無法找到的,只有在聯機的MSDN裡,Win32 and COM Development下的WMI下才能找到,同樣可以使用的類還有很多很多,包含登入使用者資訊的Win32_Account類、包含本地和共用印表機資訊的Win32_PrinterShare類等等。Win32_LogicalDisk裡所包含的磁碟機屬性相當豐富,如:

  然後使用該指定的SelectQuery查詢建立ManagementObjectSearcher執行個體,此類是用於檢索管理資訊的較為常用的進入點之一,執行個體建立結束,我們需要調用Get方法執行查詢以便檢索管理對象的集合,當調用該方法時,ManagementObjectSearcher 在指定的範圍內執行給定的查詢,並返回與 ManagementObjectCollection 中的查詢匹配的管理對象的集合,這是就可以在一個迴圈中遍曆集合中的所有對象,並擷取我們所感興趣的對象的屬性,代碼如下:

……
SelectQuery selectQuery = new SelectQuery("select * from win32_logicaldisk");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(selectQuery);

int i=0;
foreach (ManagementObject disk in searcher.Get()) {
 //擷取磁碟機盤符
 listView1.Items.Add(disk["Name"].ToString());
}
……

三、 程式實現

  我們使用Visual Studio 2005來建立該樣本程式,首先建立C#的Windows應用程式空白項目,為解決方案和項目取名為 GetLogicDrives,在預設的Form1表單上我們各放置一個ListView和一個Button控制項,保留控制項的預設名稱不變,將ListView1的View屬性設為Details,雙擊ListView1的Columns屬性,為詳細資料檢視添加5個列,分別為:盤符、卷標、類型、容量和可用空間,設定Button1的Text屬性為Refresh,為該Button1添加單擊事件,代碼如下:

private void button1_Click(object sender, EventArgs e)
{
 listView1.Items.Clear();
 SelectQuery selectQuery = new SelectQuery("select * from win32_logicaldisk");
 ManagementObjectSearcher searcher = new ManagementObjectSearcher(selectQuery);
 int i=0;
 foreach (ManagementObject disk in searcher.Get()) {
  //盤符
  listView1.Items.Add(disk["Name"].ToString());
  //卷標
  try
  {
   listView1.Items[i].SubItems.Add(disk["VolumeName"].ToString());
  }
  catch
  {
   listView1.Items[i].SubItems.Add("裝置未準備好");
  }
  //磁碟機類型
  string DriveType;
  try
  {
   DriveType = disk["DriveType"].ToString();
   switch (DriveType)
   {
    case "0":
     listView1.Items[i].SubItems.Add("未知裝置");
     break;
    case "1":
     listView1.Items[i].SubItems.Add("未分區");
     break;
    case "2":
     listView1.Items[i].SubItems.Add("可移動磁碟");
     break;
    case "3":
     listView1.Items[i].SubItems.Add("硬碟");
     break;
    case "4":
     listView1.Items[i].SubItems.Add("網路磁碟機");
     break;
    case "5":
     listView1.Items[i].SubItems.Add("光碟機");
     break;
    case "6":
     listView1.Items[i].SubItems.Add("記憶體磁碟");
     break;
  }

 }
 catch
 {
  listView1.Items[i].SubItems.Add("未知類型");
 }
 //容量
 try
 {
  listView1.Items[i].SubItems.Add(GetSizeUseUnit(disk["Size"].ToString()));
 }
 catch
 {
  listView1.Items[i].SubItems.Add("裝置未準備好");
 }
 //剩餘空間
 try
 {
  listView1.Items[i].SubItems.Add(GetSizeUseUnit(disk["FreeSpace"].ToString()));
 }
 catch
 {
  listView1.Items[i].SubItems.Add("裝置未準備好");
 }
 i++;
}
}

  我們使用了格式化顯示磁碟空間容量的自訂函數GetSizeUseUnit,當不使用該函數時磁碟容量和可用空間的顯示如下:

private string GetSizeUseUnit(string size)
{
 double dSpace = Convert.ToDouble(size);
 string sSpace = dSpace.ToString("N");
 string[] tmp;
 string rtnSize = "0";

 tmp = sSpace.Split(',');
 switch (tmp.GetUpperBound(0))
 {
  case 0:
   rtnSize = tmp[0] + " 位元組";
   break;
  case 1:
   rtnSize = tmp[0] + "." + tmp[1].Substring(0,2) + " K";
   break;
  case 2:
   rtnSize = tmp[0] + "." + tmp[1].Substring(0, 2) + " M";
   break;
  case 3:
   rtnSize = tmp[0] + "." + tmp[1].Substring(0, 2) + " G";
   break;
  case 4:
   rtnSize = tmp[0] + "." + tmp[1].Substring(0, 2) + " T";
   break;
 }
 return rtnSize;
}

  使用了上述自訂格式化顯示的函數後,磁碟容量和可用空間的顯示就顯得非常簡潔和直觀。

  最後,為了確保在表單啟動時自動擷取磁碟機資訊,需要在表單的Load事件中類比對Button1的單擊操作,代碼如下:

private void Form1_Load(object sender, EventArgs e)
{
 button1_Click(sender, e);
}

  四、 總結
 
  我們利用.Net架構System.Management 命名空間所提供的WMI封裝非常簡單的實現了擷取邏輯磁碟機的詳細資料,除了上述資訊我們還可以輕鬆的擷取Windows資源大部分資訊,比起使用Win32API要更加簡單和有效。該樣本程式在Windows XP SP2 + Visual Studio 2005 下編譯和調試通過

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.