我们如何使用严格选项来运行此代码?

时间:2017-03-22 08:09:47

标签: vb.net

Public Class Form1  
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        lblSystemSerialNumbers.Text = SystemSerialNumber()
        lblCpuIds.Text = CpuId()
    End Sub

    Private Function SystemSerialNumber() As String
        ' Get the Windows Management Instrumentation object.
        Dim wmi As Object = GetObject("WinMgmts:")

        ' Get the "base boards" (mother boards).
        Dim serial_numbers As String = ""
        Dim mother_boards As Object = wmi.InstancesOf("Win32_BaseBoard")
        For Each board As Object In mother_boards
            serial_numbers &= ", " & board.SerialNumber
        Next board
        If serial_numbers.Length > 0 Then serial_numbers = serial_numbers.Substring(2)

        Return serial_numbers
    End Function

    Private Function CpuId() As String
        Dim computer As String = "."
        Dim wmi As Object = GetObject("winmgmts:" & _
            "{impersonationLevel=impersonate}!\\" & _
            computer & "\root\cimv2")
        Dim processors As Object = wmi.ExecQuery("Select * from Win32_Processor")

        Dim cpu_ids As String = ""
        For Each cpu As Object In processors
            cpu_ids = cpu_ids & ", " & cpu.ProcessorId
        Next cpu
        If cpu_ids.Length > 0 Then cpu_ids = cpu_ids.Substring(2)

        Return cpu_ids
    End Function
End Class

此代码将检索CPU ID和主板ID。即使启用了选项严格,我如何确保这仍然有效。

为什么这可能是一个问题?

嗯,让我们看看。 wmi的类型是Object。那个wmi不一定支持像InstancesOf和SerialNumber

这样的方法

那么我们怎么能把它拉出来呢?

我认为从GetObject获取的对象不仅仅是纯对象。我认为我们应该输入或指示将其转换为更合适的类型。更合适的类型将支持InstancesOf,SerialNumber等方法

然而,适当的类型是什么?

1 个答案:

答案 0 :(得分:2)

您可以使用System.Management.dll程序集中托管的WMI类中的ManagementObjectSearcher (并且您需要添加适当的参考)。

通过这种方式,您可以将SystemSerialNumber写为

Private Function SystemSerialNumber(computer As String) As String

    Dim wmi = New ManagementObjectSearcher(computer & "\root\cimv2", "select * from Win32_BaseBoard")

    Dim boards = New List(Of String)()
    For Each board In wmi.Get()
        Dim temp = board.Properties("SerialNumber").Value?.ToString()
        If Not String.IsNullOrEmpty(temp) Then
            boards.Add(temp)
        End If
    Next board
    Return String.Join(", ", boards)
End Function

CpuId函数有点复杂,因为你想设置Impersonate标志但是仍然可以围绕WMI接口的.NET包装类编写一个方法

Private Function CpuId(computer As String) As String
    Dim cpu = New List(Of String)()

    Dim options = New ConnectionOptions()
    options.Impersonation = System.Management.ImpersonationLevel.Impersonate

    Dim scope = New ManagementScope(computer & "\root\cimv2", options)
    scope.Connect()

    Dim query = New ObjectQuery("Select * from Win32_Processor")
    Dim wmi = New ManagementObjectSearcher(scope, query)
    For Each m As ManagementObject In wmi.Get()
        Dim temp = m.Properties("ProcessorId").Value?.ToString()
        If Not String.IsNullOrEmpty(temp) Then
            cpu.Add(temp)
        End If
    Next
    Return String.Join(", ", cpu)
End Function