.netvb.netwmiwmi-query

WmiMonitorID - Converting the results to ASCII


Am attempting to query the serial number and the model of the monitor.
I managed to use the WMI code creator to generate the below code:

Try
    Dim MInfo As New ManagementObjectSearcher("root\WMI", "SELECT * FROM WmiMonitorID")

    For Each Monitor In MInfo.Get()
        If Monitor("SerialNumberID") Is Nothing Then
            MsgBox("NA")
        Else
            Dim arrSerialNumberID As UInt16()
            arrSerialNumberID = Monitor("SerialNumberID")
            For Each arrValue As UInt16 In arrSerialNumberID
                Console.WriteLine("Serial: " & arrValue)
            Next
        End If
        If Monitor("UserFriendlyName") Is Nothing Then
            MsgBox("NA")
        Else
            Dim arrSerialNumberID As UInt16()
            arrSerialNumberID = Monitor("UserFriendlyName")
            For Each arrValue As UInt16 In arrSerialNumberID
                Console.WriteLine("Model: " & arrValue)
            Next
        End If
    Next
Catch err As ManagementException
    MessageBox.Show("An error occurred while querying for WMI data: " & err.Message)
 End Try

The output is as per below:

SerialNumberID: 67,78,75,52,49,49,49,49,55,57,0,0,0,0,0,0    
UserFriendlyName: 104,112,32,76,49,53,51,48,0,0,0,0,0

I am trying to convert the output to ASCII.


Solution

  • The returned array needs to be converted to a string, to become human-eye-friendly.
    The UInt16 byte array can be converted with Convert.ToByte(UInt16), then transformed into string with Encoding.UTF8.GetString().

    Here, a conversion method is included in a specialized class (MonitorID) that is used to return some information on all Monitors in a System, querying \WMI\WmiMonitorID.
    It could be extended with \CIMV2\Win32_DesktopMonitor

    You can use it this way:

    Dim MonitorIds As List(Of MonitorID) = GetDesktopMonitorsID()
    

    Will return (among other details):

    MonitorIds(0).SerialNumberID = CNK4111179  
    MonitorIds(0).UserFriendlyName = HP L1530  
    

    Class and WMI Query method:

    Imports System.Management
    
    Public Class MonitorID
        Public Property Active As Boolean?
        Public Property InstanceName As String
        Public Property ManufacturerName As String
        Public Property ProductCodeID As String
        Public Property SerialNumberID As String
        Public Property UserFriendlyName As String
        Public Property WeekOfManufacture As String
        Public Property YearOfManufacture As String
    
        Public Shared Function ConvertToString(mObject As Object) As String
            If mObject Is Nothing Then Return String.Empty
            Return Encoding.UTF8.GetString(CType(mObject, UInt16()).
                TakeWhile(Function(ui) ui <> 0).Select(Function(ui) Convert.ToByte(ui)).ToArray())
        End Function
    End Class
    
    
    Public Shared Function GetDesktopMonitorsID() As List(Of MonitorID)
        Dim MonitorsIds As New List(Of MonitorID)()
    
        Dim ConnOptions As New ConnectionOptions() With {
            .EnablePrivileges = True,
            .Timeout = EnumerationOptions.InfiniteTimeout
        }
    
        Dim mOptions As New EnumerationOptions() With {
            .Rewindable = False,
            .ReturnImmediately = True,
            .DirectRead = True,
            .EnumerateDeep = False
        }
    
        Dim mQuery As New SelectQuery("SELECT * FROM WmiMonitorID")
        Dim mScope As New ManagementScope($"\\{Environment.MachineName}\root\WMI", ConnOptions)
        mScope.Connect()
    
        Using moSearcher As New ManagementObjectSearcher(mScope, mQuery, mOptions)
            For Each moMonitor As ManagementObject In moSearcher.[Get]()
    
            MonitorsIds.Add(New MonitorID() With {
                .Active = CType(moMonitor("Active"), Boolean?),
                .InstanceName = moMonitor("InstanceName")?.ToString(),
                .ManufacturerName = MonitorID.ConvertToString(moMonitor("ManufacturerName")),
                .ProductCodeID = MonitorID.ConvertToString(moMonitor("ProductCodeID")),
                .SerialNumberID = MonitorID.ConvertToString(moMonitor("SerialNumberID")),
                .UserFriendlyName = MonitorID.ConvertToString(moMonitor("UserFriendlyName")),
                .WeekOfManufacture = moMonitor("WeekOfManufacture")?.ToString(),
                .YearOfManufacture = moMonitor("YearOfManufacture")?.ToString()
            })
            Next
        End Using
        Return MonitorsIds
    End Function