WMI 索引

Windows Vista

下文是以 Microsoft Windows Vista 作業系統的預先發行版為基礎,這表示文中討論的功能可能會有所異動:某些功能可能會因行銷、技術或其他因素而不包含在最終產品中。如果發生這類變更,我們將盡全力更新本文內容。

WMI 索引

假設您剛搬到新市鎮,第一件要做的事,當然是添購食物。因不熟悉周圍環境,您問旁門的鄰居雜貨店在哪。您的鄰居給您像這樣的路線指引:

「直走過兩條街,然後在紅綠燈右轉,在下個街口再右轉,然後到下個街口右轉。到下個街口,再右轉一次,雜貨店就在你的右手邊的半路上。」

您開始遵循這些路線指引,可是您過了一條街沒多久就在您的右手邊看到雜貨店。要是您還是搞不清,這裡有張地圖。藍色的實線顯示鄰居的指引,紅色虛線是您的路線:

繞著物件轉

為什麼您的鄰居指引您繞了一大圈,就只為了到那家您開車直接路過的雜貨店呢?有個可能的解釋是該條街上有不只一家雜貨店,而您的鄰居希望您繞一繞好貨比三家。可是這條到這家店的路線好像很多餘。

直到現在,WMI 都要求您走鄰居的路線,對物件集合繞迴圈,以確定您找得到全部的物件。拿這個指令碼來說,它會傳回已安裝作業系統的名稱。

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colOperatingSystems = objWMIService.ExecQuery _
    ("Select * from Win32_OperatingSystem")

For Each objOperatingSystem in colOperatingSystems
    Wscript.Echo "Caption: " & objOperatingSystem.Caption
Next


如您所見,我們連線到本機機器上的 WMI 服務,查詢 Win32_OperatingSystem 類別以取得電腦上的作業系統集合,然後對該集合繞迴圈,而每個會回應作業系統的名稱。可是等一等,我們不可能有超過一個作業系統呀。我們何必要繞一大圈,就只為了尋找一個作業系統呢?為什麼不直接到那一個物件呢?假如您在指令碼中心上讀過很多篇文章,很有可能會讀到像這樣的內容:

「即使我們的集合中可能只有一個作業系統,我們還是需要設定 For Each 迴圈來繞過該迴圈。」

就跟即使只有一家店我們的鄰居卻指引我們要大繞街口一圈,是一樣的道理,我們必須指引指令碼即使集合中可能只有一個物件,還是要對集合繞迴圈。好像有點笨,是吧?好在 Windows Vista 變聰明了,為了不要變更像是 Win32_OperatingSystem 的物件只傳回單一項目而不是整個集合 (因為這會中斷所有使用該物件的現有應用程式),WMI 小組想出了一個辦法直接存取該項目:即 ItemIndex 屬性。使用 ItemIndex,在 Windows Vista 中您不需要再對集合繞迴圈,而可以直接存取個別物件。就像這樣:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colOperatingSystems = objWMIService.ExecQuery _
    ("Select * from Win32_OperatingSystem")

Wscript.Echo "Caption: " & objOperatingSystem.ItemIndex(0).Caption


ItemIndex 屬性可與衍生自 SWbemObjectSet 的任何集合搭配使用。此一新屬性除了對於像是永遠只會傳回一個項目的 Win32_OperatingSystem 集合很實用之外,您還可以將之用來存取較大集合內的任何項目。比方說,您可以如下存取電腦上所有的服務:

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colServices = objWMIService.ExecQuery _
    ("Select * from Win32_Service")

For i = 0 to colServices.Count - 1
    Wscript.Echo i & " = " & colServices.ItemIndex(i).Name
Next


沒錯,我們知道,這跟目前透過集合來讀取的方法比起來並沒有比較簡單。可是您也能直接存取集合當中任何個別的項目。您只想擷取集合中第三和第四個服務上的資訊嗎?簡單得很 (不過還是得記住,集合元素是以零開始,所以第三和第四個服務將在位置 2 和 3)。

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colServices = objWMIService.ExecQuery _
    ("Select * from Win32_Service")

Wscript.Echo colServices.ItemIndex(2).Name
Wscript.Echo colServices.ItemIndex(3).Name


當然啦,您不可能知道集合中第三和第四個項目是什麼,因為您不能預期服務以特定的順序傳回。儘管如此還是很有趣。最基本的是,您在 Windows Vista 中不需要再提供指引,在其實只有一個地方可以逛的情況下繞整個鄰近地帶。加上最近的油價高漲,這肯定是件好事。

相关链接

顯示: