2017-03-22 2 views
0
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 

Dieser Code ruft die CPU-ID und die Motherboard-ID ab. Wie kann ich sicherstellen, dass dies auch dann funktioniert, wenn Option strict aktiviert ist?Wie können wir diesen Code mit der Option strict on ausführen lassen?

Warum könnte das ein Problem sein?

Nun, mal sehen. Der Typ von wmi ist Objekt. Das wmi unterstützt nicht unbedingt Methoden wie InstancesOf und SerialNumber

Also, wie können wir das herausziehen?

Ich denke Objekt, das wir von GetObject bekommen haben, ist nicht nur reines Objekt. Ich denke, wir sollten ctype oder direkt in einen passenderen Typ umwandeln. Dieser geeignetere Typ unterstützt Methoden wie InstancesOf, SerialNumber usw.

Welche sind jedoch die entsprechenden Typen?

+2

Haben Sie versucht, das GetObject zu ändern und den ManagementObjectSearcher und seine Klassen zu verwenden? – Steve

+0

Ich verstehe nicht einmal, was es bedeutet –

+0

Der Typ von WMI ist com-Objekte übrigens. Gibt es eine Wrapperklasse, in der ich ctype machen kann? Meinst Du das? –

Antwort

2

Sie könnten die ManagementObjectSearcher aus den WMI-Klassen innerhalb der System.Management.dll-Assembly gehostet verwenden.
(Und Sie müssen die entsprechende Referenz hinzufügen).

Auf diese Weise können Sie die SystemSerialNumber als

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 

Die CPUID-Funktion schreiben könnte, ist ein wenig komplexer, da Sie die Impersonate-Flags gesetzt werden soll, aber es ist immer noch möglich, ein Verfahren um die NET-Wrapper-Klassen zu schreiben für WMI-Schnittstellen

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 
Verwandte Themen