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
或
\\.\root\cimv2: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
Public Class QueryInfo
Public ServerName As String = "."
Public NamespacePath As String = "root\cimv2"
Public RelativePath As String
Public UserName As String
Public Password As String
End Class
End Namespace
Query.vb
Public Class Query
Private 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() As QueryInfo
Get
Return gQueryInfo
End Get
End Property
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _
Public Shared ReadOnly Property ManagementPath() As System.Management.ManagementPath
Get
Return gManagementPath
End Get
End Property
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _
Public Shared ReadOnly Property ConnectionOptions() As System.Management.ConnectionOptions
Get
Return gConnectionOptions
End Get
End Property
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _
Public Shared ReadOnly Property ObjectGetOptions() As System.Management.ObjectGetOptions
Get
Return gObjectGetOptions
End Get
End Property
<System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _
Public Shared ReadOnly Property EnumerationOptions() As System.Management.EnumerationOptions
Get
Return gEnumerationOptions
End Get
End Property
Shared 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()
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() As System.Management.ManagementObjectCollection
Connect()
Return (New System.Management.ManagementClass(gManagementScope, gManagementPath, gObjectGetOptions)).GetInstances
End Function
Private Shared 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(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(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(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(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(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 Class
End Namespace
Delegate.vb
Public Delegate Sub GetCurentManagementObjectHandler(ByVal e As System.Management.ManagementObject)
Public Delegate Sub GetCurentPropertyDataHandler(ByVal e As System.Management.PropertyData)
End Namespace
SimpleQuery.vb
Public Class SimpleQuery
Public Shared Event CurrentManagementObject As GetCurentManagementObjectHandler
Public Shared Event CurrentPropertyData As GetCurentPropertyDataHandler
Private Sub New()
End Sub
Shared Sub New()
End Sub
Public Shared WriteOnly Property ServerName() As String
Set(ByVal value As String)
Query.QueryInfo.ServerName = value
End Set
End Property
Public Shared WriteOnly Property UserName() As String
Set(ByVal value As String)
Query.QueryInfo.UserName = value
End Set
End Property
Public Shared WriteOnly Property Password() As String
Set(ByVal value As String)
Query.QueryInfo.Password = value
End Set
End Property
Public Shared WriteOnly Property EnumerateDeep() As Boolean
Set(ByVal value As Boolean)
Query.EnumerationOptions.EnumerateDeep = value
End Set
End Property
Public Shared 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(ByVal e As System.Management.ManagementObject)
RaiseEvent CurrentManagementObject(e)
Query.MoveNext(e, AddressOf OutPutPropertyData)
End Sub
Private Shared Sub OutPutPropertyData(ByVal e As System.Management.PropertyData)
RaiseEvent CurrentPropertyData(e)
End Sub
End Class
End Namespace
WMIClass.vb
Public Class WMIClass
Private Sub New()
End Sub
Private Shared gAll(-1) As String
Private Shared gIndex As Integer = 0
Public Shared ReadOnly Property All() As String()
Get
Return gAll
End Get
End Property
Shared 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(ByVal obj As System.Management.ManagementObject)
gAll(gIndex) = obj("__Class").ToString
gIndex += 1
End Sub
End Class
End Namespace
以下为使用方法:
为了显示查询出来的信息,我这里仅取Properties,读取的是里头的PropertyData信息。为此,在应用项目中,用了下面一个类来简单获取:
Public Class PropertyDataInfo
Private gName As String
Private gValue As String
Private gIsArray As Boolean = False
Private gStatus As Boolean = True
Sub New()
End Sub
Public 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() As String
Get
Return gName
End Get
Set(ByVal value As String)
gName = value
End Set
End Property
Public Property Value() As String
Get
Return gValue
End Get
Set(ByVal value As String)
gValue = value
End Set
End Property
Public Property IsArray() As Boolean
Get
Return gIsArray
End Get
Set(ByVal value As Boolean)
gIsArray = value
End Set
End Property
Public Property Status() As Boolean
Get
Return gStatus
End Get
Set(ByVal value As Boolean)
gStatus = value
End Set
End Property
Public Sub Clear()
gName = Nothing
gValue = Nothing
gIsArray = False
gStatus = True
End Sub
Public Shadows Function ToString() As String
Return String.Format("属性:{0},值:{1},数组:{2},状态:{3}", gName, gValue, gIsArray, gStatus)
End Function
End Class
上面状态为False时表示无法读取该属性值。数组为True表示该属性的值类型是一数组。
使用时的大概代码是这样的:
Public Class Form1
Dim mItem As New PropertyDataInfo
Private Delegate Sub SetTextCallback(ByVal [text] As String)
Private Sub SetLoadingLableText(ByVal [text] As String)
Me.ListBox1.Items.Add([text])
End Sub
Private 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(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonClear.Click
ListBox1.Items.Clear()
End Sub
Private Sub ButtonQuery_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonQuery.Click
Start()
End Sub
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
Private Sub GetCurentManagementObject(ByVal e As System.Management.ManagementObject)
ListBoxItemAdd("")
ListBoxItemAdd(e.ToString)
mItem.Clear()
End Sub
Private Sub GetCurentPropertyData(ByVal e As System.Management.PropertyData)
mItem.GetData(e)
ListBoxItemAdd(mItem.ToString)
End Sub
Private 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(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 Sub
End Class