Author:水如烟
WMI的查询在日常计算机和网络管理中经常会用到。本项目的目的是使WMI查询变得简单一些。
功能:以给出的身份查询某台机的WMI提供的信息
使用方式(示):示图 Private Sub Start()
ListBoxItemAdd(String.Format("Begin AT {0}", Now.ToString))
ListBoxItemAdd("")
LzmTW.WMI.SimpleQuery.ServerName = Me.TextBoxServerName.Text
LzmTW.WMI.SimpleQuery.UserName = Me.TextBoxUserName.Text '为空时以当前身份查询
LzmTW.WMI.SimpleQuery.Password = Me.TextBoxPassword.Text
LzmTW.WMI.SimpleQuery.EnumerateDeep = Me.CheckBoxEnumerateDeep.Checked
Try
LzmTW.WMI.SimpleQuery.Excute(Me.ComboBoxSelect.Text)
Catch ex As Exception
ListBoxItemAdd(String.Format("Error! Msg:{0}", ex.Message))
End Try
ListBoxItemAdd("")
ListBoxItemAdd(String.Format("End AT {0}", Now.ToString))
End Sub
其中接受查询内容的Me.ComboBoxSelect.Tex文本可以是这样的:
Win32_Desktop
或
\.rootcimv2:Win32_Desktop.Name="NT AUTHORITY\\LOCAL SERVICE"
或
Win32_Desktop.Name="NT AUTHORITY\\LOCAL SERVICE"
或
SELECT NAME FROM Win32_Desktop
以下为主项目:
项目引用System.Management命名,共有五个文件,在命名空间LzmTW之内,生成LzmTW.WMI.Dll文件。
五个文件分别是:QueryInfo.vb,Query.vb,Delegate.vb,SimpleQuery.vb,WMIClass.vb。
QueryInfo.vb
Namespace WMINamespace WMI Public Class QueryInfoClass QueryInfo Public ServerName As String = "." Public NamespacePath As String = "root\cimv2" Public RelativePath As String Public UserName As String Public Password As String End ClassEnd NamespaceQuery.vb
Namespace WMINamespace WMI Public Class QueryClass Query Private Sub New()Sub New() End Sub Private Shared gQueryInfo As New QueryInfo Private Shared gManagementPath As System.Management.ManagementPath Private Shared gConnectionOptions As System.Management.ConnectionOptions Private Shared gManagementScope As System.Management.ManagementScope Private Shared gObjectGetOptions As System.Management.ObjectGetOptions Private Shared gEnumerationOptions As System.Management.EnumerationOptions Public Shared ReadOnly Property QueryInfo()Property QueryInfo() As QueryInfo Get Return gQueryInfo End Get End Property <System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _ Public Shared ReadOnly Property ManagementPath()Property ManagementPath() As System.Management.ManagementPath Get Return gManagementPath End Get End Property <System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _ Public Shared ReadOnly Property ConnectionOptions()Property ConnectionOptions() As System.Management.ConnectionOptions Get Return gConnectionOptions End Get End Property <System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _ Public Shared ReadOnly Property ObjectGetOptions()Property ObjectGetOptions() As System.Management.ObjectGetOptions Get Return gObjectGetOptions End Get End Property <System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _ Public Shared ReadOnly Property EnumerationOptions()Property EnumerationOptions() As System.Management.EnumerationOptions Get Return gEnumerationOptions End Get End Property Shared Sub New()Sub New() gManagementPath = New System.Management.ManagementPath gConnectionOptions = New System.Management.ConnectionOptions gObjectGetOptions = New System.Management.ObjectGetOptions gEnumerationOptions = New System.Management.EnumerationOptions End Sub Private Shared Sub Connect()Sub Connect() With gManagementPath .Server = gQueryInfo.ServerName .NamespacePath = gQueryInfo.NamespacePath .RelativePath = gQueryInfo.RelativePath End With If gQueryInfo.UserName IsNot Nothing Then gQueryInfo.UserName = gQueryInfo.UserName.Trim If gQueryInfo.UserName = "" Then QueryInfo.UserName = Nothing QueryInfo.Password = Nothing End If Else gQueryInfo.Password = Nothing End If With gConnectionOptions .Username = gQueryInfo.UserName .Password = gQueryInfo.Password End With If gManagementScope IsNot Nothing Then gManagementScope = Nothing gManagementScope = New System.Management.ManagementScope(gManagementPath, gConnectionOptions) gManagementScope.Connect() End Sub Private Shared Function Excute0()Function Excute0() As System.Management.ManagementObjectCollection Connect() Return (New System.Management.ManagementClass(gManagementScope, gManagementPath, gObjectGetOptions)).GetInstances End Function Private Shared Function Excute1()Function Excute1(ByVal query As String) As System.Management.ManagementObjectCollection Connect() Return (New System.Management.ManagementObjectSearcher(gManagementScope, New System.Management.ObjectQuery(query), gEnumerationOptions)).Get End Function Public Shared Function GetManagementObject()Function GetManagementObject(ByVal relativepath As String) As System.Management.ManagementObject QueryInfo.RelativePath = relativepath Connect() Return New System.Management.ManagementObject(gManagementScope, gManagementPath, gObjectGetOptions) End Function Public Shared Function GetManagementObjectCollection()Function GetManagementObjectCollection(ByVal ClassOrSelectString As String) As System.Management.ManagementObjectCollection Dim tmp As Management.ManagementObjectCollection = Nothing ClassOrSelectString = ClassOrSelectString.Trim.ToUpper If ClassOrSelectString.StartsWith("SELECT") Then tmp = Excute1(ClassOrSelectString) Else QueryInfo.RelativePath = ClassOrSelectString tmp = Excute0() End If Return tmp End Function <System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _ Public Shared Sub MoveNext()Sub MoveNext(ByVal mgmtObjectCollection As System.Management.ManagementObjectCollection, ByVal action As Action(Of System.Management.ManagementObject)) MoveNext(Of System.Management.ManagementObject)(mgmtObjectCollection.GetEnumerator, action) End Sub <System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _ Public Shared Sub MoveNext()Sub MoveNext(ByVal mgmtObject As System.Management.ManagementObject, ByVal action As Action(Of System.Management.PropertyData)) MoveNext(Of System.Management.PropertyData)(mgmtObject.Properties.GetEnumerator, action) End Sub <System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _ Public Shared Sub MoveNext()Sub MoveNext(Of T)(ByVal enumerator As IEnumerator, ByVal action As Action(Of T)) If (enumerator Is Nothing) Then Throw New ArgumentNullException("enumerator") End If If (action Is Nothing) Then Throw New ArgumentNullException("action") End If While enumerator.MoveNext action.Invoke(CType(enumerator.Current, T)) End While End Sub End ClassEnd NamespaceDelegate.vb
Namespace WMINamespace WMI Public Delegate Sub GetCurentManagementObjectHandler()Sub GetCurentManagementObjectHandler(ByVal e As System.Management.ManagementObject) Public Delegate Sub GetCurentPropertyDataHandler()Sub GetCurentPropertyDataHandler(ByVal e As System.Management.PropertyData)End NamespaceSimpleQuery.vb
Namespace WMINamespace WMI Public Class SimpleQueryClass SimpleQuery Public Shared Event CurrentManagementObject As GetCurentManagementObjectHandler Public Shared Event CurrentPropertyData As GetCurentPropertyDataHandler Private Sub New()Sub New() End Sub Shared Sub New()Sub New() End Sub Public Shared WriteOnly Property ServerName()Property ServerName() As String Set(ByVal value As String) Query.QueryInfo.ServerName = value End Set End Property Public Shared WriteOnly Property UserName()Property UserName() As String Set(ByVal value As String) Query.QueryInfo.UserName = value End Set End Property Public Shared WriteOnly Property Password()Property Password() As String Set(ByVal value As String) Query.QueryInfo.Password = value End Set End Property Public Shared WriteOnly Property EnumerateDeep()Property EnumerateDeep() As Boolean Set(ByVal value As Boolean) Query.EnumerationOptions.EnumerateDeep = value End Set End Property Public Shared Sub Excute()Sub Excute(ByVal mgmtSql As String) If mgmtSql Is Nothing Then mgmtSql = "" If mgmtSql.IndexOf("."c) <> -1 Then OutPutManageMentObject(Query.GetManagementObject(mgmtSql)) Else Query.MoveNext(Query.GetManagementObjectCollection(mgmtSql), AddressOf OutPutManageMentObject) End If End Sub Private Shared Sub OutPutManageMentObject()Sub OutPutManageMentObject(ByVal e As System.Management.ManagementObject) RaiseEvent CurrentManagementObject(e) Query.MoveNext(e, AddressOf OutPutPropertyData) End Sub Private Shared Sub OutPutPropertyData()Sub OutPutPropertyData(ByVal e As System.Management.PropertyData) RaiseEvent CurrentPropertyData(e) End Sub End ClassEnd NamespaceWMIClass.vb
Namespace WMINamespace WMI Public Class WMIClassClass WMIClass Private Sub New()Sub New() End Sub Private Shared gAll(-1) As String Private Shared gIndex As Integer = 0 Public Shared ReadOnly Property All()Property All() As String() Get Return gAll End Get End Property Shared Sub New()Sub New() Dim tmpRoot As New System.Management.ManagementClass() Dim tmpOptions As New System.Management.EnumerationOptions() tmpOptions.EnumerateDeep = True Dim tmpObjects As System.Management.ManagementObjectCollection = tmpRoot.GetSubclasses(tmpOptions) ReDim gAll(tmpObjects.Count - 1) Using tmpObjects Query.MoveNext(Of Management.ManagementObject)(tmpObjects.GetEnumerator, AddressOf GetAllClass) End Using Array.Sort(gAll) tmpOptions = Nothing tmpRoot = Nothing End Sub Private Shared Sub GetAllClass()Sub GetAllClass(ByVal obj As System.Management.ManagementObject) gAll(gIndex) = obj("__Class").ToString gIndex += 1 End Sub End ClassEnd Namespace以下为使用方法:
为了显示查询出来的信息,我这里仅取Properties,读取的是里头的PropertyData信息。为此,在应用项目中,用了下面一个类来简单获取:
<Serializable()> _Public Class PropertyDataInfoClass PropertyDataInfo Private gName As String Private gValue As String Private gIsArray As Boolean = False Private gStatus As Boolean = True Sub New()Sub New() End Sub Public Sub GetData()Sub GetData(ByVal obj As Management.PropertyData) With obj gName = .Name gIsArray = .IsArray gStatus = True Try If gIsArray Then gValue = String.Join(",", CType(obj.Value, String())) Else gValue = obj.Value.ToString End If Catch ex As Exception gValue = "" gStatus = False End Try End With End Sub Public Property Name()Property Name() As String Get Return gName End Get Set(ByVal value As String) gName = value End Set End Property Public Property Value()Property Value() As String Get Return gValue End Get Set(ByVal value As String) gValue = value End Set End Property Public Property IsArray()Property IsArray() As Boolean Get Return gIsArray End Get Set(ByVal value As Boolean) gIsArray = value End Set End Property Public Property Status()Property Status() As Boolean Get Return gStatus End Get Set(ByVal value As Boolean) gStatus = value End Set End Property Public Sub Clear()Sub Clear() gName = Nothing gValue = Nothing gIsArray = False gStatus = True End Sub Public Shadows Function ToString()Function ToString() As String Return String.Format("属性:{0},值:{1},数组:{2},状态:{3}", gName, gValue, gIsArray, gStatus) End FunctionEnd Class上面状态为False时表示无法读取该属性值。数组为True表示该属性的值类型是一数组。
使用时的大概代码是这样的:
Public Class Form1Class Form1 Dim mItem As New PropertyDataInfo Private Delegate Sub SetTextCallback()Sub SetTextCallback(ByVal [text] As String) Private Sub SetLoadingLableText()Sub SetLoadingLableText(ByVal [text] As String) Me.ListBox1.Items.Add([text]) End Sub Private Sub ListBoxItemAdd()Sub ListBoxItemAdd(ByVal message As String) If Me.ListBox1.InvokeRequired Then Dim d As New SetTextCallback(AddressOf SetLoadingLableText) Me.Invoke(d, New Object() {message}) Else SetLoadingLableText(message) End If Application.DoEvents() End Sub Private Sub ButtonClear_Click()Sub ButtonClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonClear.Click ListBox1.Items.Clear() End Sub Private Sub ButtonQuery_Click()Sub ButtonQuery_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonQuery.Click Start() End Sub Private Sub Start()Sub Start() ListBoxItemAdd(String.Format("Begin AT {0}", Now.ToString)) ListBoxItemAdd("") LzmTW.WMI.SimpleQuery.ServerName = Me.TextBoxServerName.Text LzmTW.WMI.SimpleQuery.UserName = Me.TextBoxUserName.Text LzmTW.WMI.SimpleQuery.Password = Me.TextBoxPassword.Text LzmTW.WMI.SimpleQuery.EnumerateDeep = Me.CheckBoxEnumerateDeep.Checked Try LzmTW.WMI.SimpleQuery.Excute(Me.ComboBoxSelect.Text) Catch ex As Exception ListBoxItemAdd(String.Format("Error! Msg:{0}", ex.Message)) End Try ListBoxItemAdd("") ListBoxItemAdd(String.Format("End AT {0}", Now.ToString)) End Sub Private Sub GetCurentManagementObject()Sub GetCurentManagementObject(ByVal e As System.Management.ManagementObject) ListBoxItemAdd("") ListBoxItemAdd(e.ToString) mItem.Clear() End Sub Private Sub GetCurentPropertyData()Sub GetCurentPropertyData(ByVal e As System.Management.PropertyData) mItem.GetData(e) ListBoxItemAdd(mItem.ToString) End Sub Private Sub Form1_Load()Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load AddHandler LzmTW.WMI.SimpleQuery.CurrentManagementObject, AddressOf GetCurentManagementObject AddHandler LzmTW.WMI.SimpleQuery.CurrentPropertyData, AddressOf GetCurentPropertyData Me.ComboBoxSelect.DataSource = LzmTW.WMI.WMIClass.All End Sub Private Sub ListBox1_SelectedIndexChanged()Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged If ListBox1.SelectedItem Is Nothing Then Exit Sub Clipboard.SetDataObject(ListBox1.SelectedItem, False) End SubEnd Class