Share via


How to get monitor friendly name in VB.net?

Question

Thursday, June 13, 2019 5:48 AM

Screen object returns the device path, resolution, etc.  But it does not return the friendly name of a display monitor. 

Need the real display name such as displayed in the control panel, not that generic junk that is displayed in the device manager.  There are a couple of C and C# examples, but none of them seem to convert over the vb .net without various issues, usually because the code is very old to begin with.  What few VB examples exist are very old and fail to work in vb.net.

What would be great is to go from... \.\DISPLAY4 which the screen object can return to the friendly name, i.e. "Dell U1703" for example.

Been searching for hours for something that actually works, really surprised that no one has documented a vb.net example that is current and functional.

All replies (6)

Thursday, June 13, 2019 7:16 AM

Hi,

I found some code,you can try it.

 Public Sub show_display_devices()
        Dim lpDisplayDevice As DISPLAY_DEVICE = New DISPLAY_DEVICE(0)
        Dim monitor_name As DISPLAY_DEVICE = New DISPLAY_DEVICE(0)
        Dim devNum As Integer = 0

        While EnumDisplayDevices(Nothing, devNum, lpDisplayDevice, 0)
            Console.WriteLine(vbLf & "devNum =" & devNum)
            Console.WriteLine("cb =" & lpDisplayDevice.cb)
            Console.WriteLine("DeviceID =" & lpDisplayDevice.DeviceID)
            Console.WriteLine("DeviceKey =" & lpDisplayDevice.DeviceKey)
            Console.WriteLine("DeviceName =" & lpDisplayDevice.DeviceName.Trim())
            Console.WriteLine("DeviceString =" & lpDisplayDevice.DeviceString.Trim())
            EnumDisplayDevices(lpDisplayDevice.DeviceName, 0, monitor_name, 0)
            Console.WriteLine("Monitor name =" & monitor_name.DeviceString.Trim())
            devNum += 1
        End While
    End Sub

    <DllImport("User32.dll")>
    Private Shared Function EnumDisplayDevices(ByVal lpDevice As String, ByVal iDevNum As Integer, ByRef lpDisplayDevice As DISPLAY_DEVICE, ByVal dwFlags As Integer) As Boolean

    End Function

    <StructLayout(LayoutKind.Sequential)>
    Public Structure DISPLAY_DEVICE
        Public cb As Integer
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)>
        Public DeviceName As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)>
        Public DeviceString As String
        Public StateFlags As Integer
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)>
        Public DeviceID As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=128)>
        Public DeviceKey As String

        Public Sub New(ByVal flags As Integer)
            cb = 0
            StateFlags = flags
            DeviceName = New String(ChrW(32), 32)
            DeviceString = New String(ChrW(32), 128)
            DeviceID = New String(ChrW(32), 128)
            DeviceKey = New String(ChrW(32), 128)
            cb = Marshal.SizeOf(Me)
        End Sub
    End Structure

Best Regards,

Alex

MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


Thursday, June 13, 2019 11:08 AM

Hello,

Add the following NuGet package (there is a good deal more to the library too)

https://www.nuget.org/packages/WindowsDisplayAPI

Then get friendly names

Imports WindowsDisplayAPI.DisplayConfig
Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        For Each target In PathDisplayTarget.GetDisplayTargets()
            Console.WriteLine(target.FriendlyName)
        Next
    End Sub
End Class

Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

NuGet BaseConnectionLibrary for database connections.

StackOverFlow


Thursday, June 13, 2019 1:32 PM

I also found this bit of code as well, see below, which does itemize the friendly names, without any 3rd party library/API.  But it does not solve the requested issue, of how to associate this information to the deviceID information the VB.Net screen object provides.

'

Imports System
Imports System.Management
Imports System.Text

'

Module MonitorModule

    '

    Public Class MonitorIdentificationClass

        '

        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(theObject As Object) As String

            Dim theString As String = String.Empty

            '

            If (Not (theObject Is Nothing)) Then

                '

                theString = Encoding.UTF8.GetString(CType(theObject, UInt16()).TakeWhile(Function(ui) ui <> 0).Select(Function(ui) Convert.ToByte(ui)).ToArray())

            End If

            Return (theString)

        End Function

    End Class

    '

    Public Function GetDesktopMonitors() As List(Of MonitorIdentificationClass)
        Dim MonitorsIds As New List(Of MonitorIdentificationClass)()

        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 MonitorIdentificationClass() With {
                    .Active = CType(moMonitor("Active"), Boolean?),
                    .InstanceName = moMonitor("InstanceName")?.ToString(),
                    .ManufacturerName = MonitorIdentificationClass.ConvertToString(moMonitor("ManufacturerName")),
                    .ProductCodeID = MonitorIdentificationClass.ConvertToString(moMonitor("ProductCodeID")),
                    .SerialNumberID = MonitorIdentificationClass.ConvertToString(moMonitor("SerialNumberID")),
                    .UserFriendlyName = MonitorIdentificationClass.ConvertToString(moMonitor("UserFriendlyName")),
                    .WeekOfManufacture = moMonitor("WeekOfManufacture")?.ToString(),
                    .YearOfManufacture = moMonitor("YearOfManufacture")?.ToString()
                })
            Next
        End Using

        Return MonitorsIds

    End Function

End Module


Thursday, June 13, 2019 1:38 PM

Sorry, but this code does not answer the question... Which is how to I get the friendly name when I have the deviceID such as returned from the VB.Net Screen object.  The above code returns the Device Managment object name only for example:

Name Value Type
string.Trim returned "Generic Non-PnP Monitor" String

The above is is not the friendly name.


Thursday, June 13, 2019 1:43 PM

Although I am sure this is one possible idea to get the friendly names, it relies on a 3rd party library/API.  Why would this be preferred to solving my request without use of a 3rd party library/API?  Moreover this does not solve the requested issue... how to I associate the friendly name to the VB.Net screen object information?


Thursday, June 13, 2019 2:03 PM

Although I am sure this is one possible idea to get the friendly names, it relies on a 3rd party library/API.  Why would this be preferred to solving my request without use of a 3rd party library/API?  Moreover this does not solve the requested issue... how to I associate the friendly name to the VB.Net screen object information?

The library is open source and is good for .NET and .NET Standard Framework. Beyond ready for both frameworks the library is pure .NET/C# code which if need be you can change the code, recompile and be good to go. The library source has been active in the past two years.

Here are the classes from the GitHub repository which when going to the NuGet library home page you click on the "Project site" link to get to the code.

Lastly, the code does not clutter up you present code.

Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

NuGet BaseConnectionLibrary for database connections.

StackOverFlow