WMI(WindowsManagementInstrumentation)技術是微軟提供的Windows下的系統管理工具。透過該工具可以在本地或管理客戶端系統中幾乎一切的資訊。很多專業的網路管理工具都是基於WMI開發的。該工具在Win2000以及WinNT下是標準工具,在Win9X下是擴充安裝選項。本文將介紹如何透過VB程式來存取WMI物件的程式設計。
首先來看一個簡單的透過WMI取得系統資訊的範例,這個範例透過WMI物件獲得系統中運作的進程:
FunctionEnum1()AsString
DimWMI
SetWMI=GetObject(WinMgmts:)
Setobjs=WMI.InstancesOf(Win32_PRocess)
ForEachobjInobjs
Enum1=Enum1 obj.Description Chr(13) Chr(10)
Next
EndFunction
在上面的程式碼中,先透過GetObject(WinMgmts:)取得WMI對象,在WMI對像下有很多的子項,在這裡我們透過WMI.InstancesOf(Win32_Process)取得系統中所有的行程列表子項。
下面看一個完整的存取WMI物件的範例,這個範例取得電腦的資訊。
建立一個新工程,在Form1中新增一個TextBox控制項以及一個CommandButton控件,在CommandButton的Click事件中寫入以下的程式碼:
PrivateSubCommand1_Click()
Dims,System,item
DimiAsInteger
SetSystem=GetObject(winmgmts:).InstancesOf(Win32_ComputerSystem)
ForEachitemInSystem
'List1.AddItemitem.cputype
s=ComputerInfo&vbCrLf
s=s&***********************&vbCrLf
s=s&電腦名稱:&item.name&vbCrLf
s=s&狀態:&item.Status&vbCrLf
s=s&型別:&item.SystemType&vbCrLf
s=s&生產廠商:&item.Manufacturer&vbCrLf
s=s&型號:&item.Model&vbCrLf
s=s&內存:~&item.totalPhysicalMemory/1024000&mb&vbCrLf
s=s&域:&item.domain&vbCrLf
's=s&工作群組&item.Workgroup&vbCrLf'取得工作群組和網域的選項不能同時使用
s=s&目前使用者:&item.username&vbCrLf
s=s&啟動狀態&item.BootupState&vbCrLf
s=s&該電腦屬於&item.PrimaryOwnerName&vbCrLf
s=s&系統類型&item.CreationClassName&vbCrLf
s=s&電腦類別類型&item.Description&vbCrLf
Fori=0To1'這裡假設安裝了兩個系統
s=s&Chr(5)&啟動選項&i&:&item.SystemStartupOptions(i)_
&vbCrLf
Nexti
Next
Text1.Text=s
EndSub
執行程序,點選Command1,在textBox中就可以顯示電腦的資訊。
在上面的程式碼中,程式透過GetObject(winmgmts:)取得WMI對象,然後取得下面的Win32_ComputerSystem子項並透過存取Win32_ComputerSystem物件中的分項來獲得系統中的資訊。
需要說明的是,並不是所有的系統都支援WMI,在有些系統中無法顯示生產廠商等資訊。
現在的電腦以及網路組成十分複雜。例如係統硬體方面就有主機板、硬碟、網路卡...。
軟體方面有作業系統、系統中安裝的軟體、正在運作的進程等等。網路方面有網域、工作小組等等。利用WMI可以存取上面的全部信息,但是如果向上面一樣的利用分項來訪問的話會很麻煩。為此,WMI提供了一個類似SQL語句的查詢語句,可以透過查詢語句來取得WMI物件下的子項。
下面是遍歷系統中安裝的網路卡並回傳網卡MAC位址的代碼:
PrivateFunctionMACAddress()AsString
Setobjs=GetObject(winmgmts:).ExecQuery(_
SELECTMACAddress&_
FROMWin32_NetworkAdapter&_
WHERE&_
((MACAddressIsNotNULL)&_
AND(Manufacturer<>&_
'Microsoft')))
ForEachobjInobjs
MACAddress=obj.MACAddress
ExitFor
Nextobj
EndFunction
上面的程式碼取得WMI對象,然後執行ExecQuery執行一個WMI查詢語句取得安裝的網路卡並傳回網卡的MAC位址。
WMI也支援事件處理,讓程式可以處理系統事件,例如程式運作、關閉,可移動磁碟機的插入、取出等。下面是一個可以對系統中執行程式進行監控的程式。
先建立一個新工程,然後點選選單的project references項,在references清單中選取MicrosoftWMIScriptingLibrary將WMI物件庫加入工程中。然後在Form1中加入一個ListBox控件,然後在Form1中加入以下程式碼:
OptionExplicit
DimLocatorAsSWbemLocator
DimServicesAsSWbemServices
DimWithEventsStatusSinkAsSWbemSink
PrivateSubKillEvents()
StatusSink.Cancel
SetStatusSink=Nothing
EndSub
PrivateSubForm_Load()
DimQueryAsString
SetStatusSink=NewSWbemSink
SetLocator=CreateObject(WbemScripting.SWbemLocator)
SetServices=Locator.ConnectServer()
Query=SELECT*FROM__InstanceCreationEvent
Query=Query WITHIN1
Query=Query WHERETargetInstanceISA'Win32_Process'
Services.ExecNotificationQueryAsyncStatusSink,Query
EndSub
PrivateSubStatusSink_OnObjectReady(ByValStatusEventAsSWbemObject,_
ByValEventContextAsSWbemNamedValueSet)
Dimarr
DimstrQueAsString
DimiAsInteger
List1.Clear
arr=Split(StatusEvent.GetObjectText_,Chr(10))
Fori=LBound(arr)ToUBound(arr)
List1.AddItemarr(i)
Nexti
EndSub
PrivateSubStatusSink_OnCompleted(ByValHResultAsWbemErrorEnum,_
ByValErrorObjectAsSWbemObject,_
ByValEventContextAsSWbemNamedValueSet)
IfHResult<>wbemErrCallCancelledThen
'錯誤處理
EndIf
EndSub
在上面的程式中定義了一個SWbemSink物件StatusSink,然後建立一個SWbemServices物件Server,並將StatusSink連接到Server物件上。這樣就可以透過StatusSink監控程式的運作。
執行程序,然後任意執行一個程序,在Form1的ListBox中就可以列出執行的程序的資訊。
WMI應用程式最強大的一面是可以透過WEB頁面來實現遠端管理。下面我們來建立一個HTML頁面,可以實作向上面的VB程式一樣動態監控系統中執行的程式。監控系統中程式運行的HTML程式碼如下:
<html>
<head>
<objectID=mysinkCLASSID=CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223></object>
</head>
<SCRIPT>
functionwindow.onload()
{
varlocator=newActiveXObject(WbemScripting.SWbemLocator);
varservice=locator.ConnectServer();
szQuery=SELECT*FROM__InstanceCreationEvent;
szQuery =WITHIN1;
szQuery =WHERETargetInstanceISA'Win32_Process';
service.ExecNotificationQueryAsync(mysink,szQuery);
}
</SCRIPT>
<scriptFOR=mysinkEVENT=OnObjectReady(obj,objAsyncContext)>
document.all.info.innerHTML =obj.TargetInstance.Name <br>;
</script>
<body>
<spanID=info></span>
</body>
</html>
儲存代碼為Htm後綴的頁面檔。雙擊開啟網頁,然後執行一個程序,在網頁上就可以列出正在執行的程序的檔案名稱。
以上簡單的介紹了一下WMI的應用,其實WMI物件的操作是十分複雜,功能也是很強大的,例如你可以透過WMI在伺服器上監控整個區域網路上的電腦、大量的電腦到區域網路上安裝軟體(例如防毒軟體)。透過頁面遠端存取伺服器,控制伺服器運行程序,新增使用者等。關於更多的WMI的應用,讀者可以訪問MSDN上WMI開發的主頁:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmistart_5kth.asp
獲取更多資訊。
->