【发布时间】:2014-09-16 13:44:23
【问题描述】:
我想知道 .NET 框架类是否提供了一种方法来检索监视器显示名称(例如:LG TV)而无需重复使用 WMI 或 WinAPI,我已经知道如何检索通过这些替代方法监视名称,这个问题是为了避免使用 API 或 WMI,以防万一它可以使用 .NET ClassLibrary 来完成,以改进一般的编码。
谢谢。
【问题讨论】:
标签: c# .net vb.net winforms screen
我想知道 .NET 框架类是否提供了一种方法来检索监视器显示名称(例如:LG TV)而无需重复使用 WMI 或 WinAPI,我已经知道如何检索通过这些替代方法监视名称,这个问题是为了避免使用 API 或 WMI,以防万一它可以使用 .NET ClassLibrary 来完成,以改进一般的编码。
谢谢。
【问题讨论】:
标签: c# .net vb.net winforms screen
据我所知,答案是NO。有 winforms 类Screen.cs 可以做一些基本的事情,但不会暴露监视器显示名称。如果有帮助,它会公开可用于进一步分析的 DeviceName:
Screen.AllScreens[0].Dump()
会给你:
Screen[Bounds={X=0,Y=0,Width=1920,Height=1200}
WorkingArea={X=0,Y=0,Width=1920,Height=1160}
Primary=True
DeviceName=\\.\DISPLAY1]
我确实启动了 MultiMonitorHelper 库,该库应该旨在“抽象”掉所有这些毫无意义的 WinAPI/WMI 乱码,但我从来没有这样做过。虽然它在我的“想做的”事情清单上:p
【讨论】:
也许通过注册表? 它将通过您的所有显示器。它将从 EDID 中返回名称。
但是,Win10 发生了变化! Win10 没有“Control”,但有一个“Properties”子键(IF/OR 处的解决方法)#untested!
Public Function GetMonitorDetails() As List(Of String())
Dim sReturn As List(Of String()) = New List(Of String())
'Open the Display Reg-Key
Dim Display As RegistryKey = Registry.LocalMachine
Dim bFailed As Boolean = False
Try
Display = Registry.LocalMachine.OpenSubKey("SYSTEM\CurrentControlSet\Enum\DISPLAY")
Catch ex As Exception
sReturn.Add({"Error", ex.Message})
bFailed = True
End Try
If Not bFailed And (Display IsNot Nothing) Then
'Get all MonitorIDss
For Each sMonitorID As String In Display.GetSubKeyNames()
Dim MonitorID As RegistryKey = Display.OpenSubKey(sMonitorID)
If MonitorID IsNot Nothing Then
'Get all Plug&Play ID's
For Each sPNPID As String In MonitorID.GetSubKeyNames()
Dim PnPID As RegistryKey = MonitorID.OpenSubKey(sPNPID)
If PnPID IsNot Nothing Then
Dim sSubkeys As String() = PnPID.GetSubKeyNames()
Dim ssSubkeys As String = String.Join(".", sSubkeys)
'Check if Monitor is active
If (ssSubkeys.Contains("Control") Or ssSubkeys.Contains("Properties")) And ssSubkeys.Contains("Device Parameters") Then
Dim DevParam As RegistryKey = PnPID.OpenSubKey("Device Parameters")
Dim sSerial As String = ""
Dim sModel As String = ""
Dim tmpMfg As String = ""
Dim tmpVer As String = ""
Dim tmpDev As String = ""
Dim iWeek As Integer = 0
Dim iYear As Integer = 0
'Define Search Keys
Dim sSerFind As New String(New Char() {ChrW(0), ChrW(0), ChrW(0), ChrW(&HFF)})
Dim sModFind As New String(New Char() {ChrW(0), ChrW(0), ChrW(0), ChrW(&HFC)})
'Get the EDID code
Dim bObj As Byte() = TryCast(DevParam.GetValue("EDID", Nothing), Byte())
If bObj IsNot Nothing Then
'Get the 4 Vesa descriptor blocks
Dim sDescriptor As String() = New String(3) {}
sDescriptor(0) = Encoding.[Default].GetString(bObj, &H36, 18)
sDescriptor(1) = Encoding.[Default].GetString(bObj, &H48, 18)
sDescriptor(2) = Encoding.[Default].GetString(bObj, &H5A, 18)
sDescriptor(3) = Encoding.[Default].GetString(bObj, &H6C, 18)
iWeek = Asc(Encoding.[Default].GetString(bObj, &H10, 1))
iYear = Asc(Encoding.[Default].GetString(bObj, &H11, 1)) + 1990
Dim tmpEDIDMfg As String
Dim Char1, Char2, Char3 As Integer
Dim Byte1, Byte2 As Byte
tmpEDIDMfg = Encoding.[Default].GetString(bObj, &H8, 2)
Char1 = 0 : Char2 = 0 : Char3 = 0
Byte1 = CByte(Asc(Left(tmpEDIDMfg, 1)))
Byte2 = CByte(Asc(Right(tmpEDIDMfg, 1)))
If (Byte1 And 64) > 0 Then Char1 = Char1 + 16
If (Byte1 And 32) > 0 Then Char1 = Char1 + 8
If (Byte1 And 16) > 0 Then Char1 = Char1 + 4
If (Byte1 And 8) > 0 Then Char1 = Char1 + 2
If (Byte1 And 4) > 0 Then Char1 = Char1 + 1
If (Byte1 And 2) > 0 Then Char2 = Char2 + 16
If (Byte1 And 1) > 0 Then Char2 = Char2 + 8
If (Byte2 And 128) > 0 Then Char2 = Char2 + 4
If (Byte2 And 64) > 0 Then Char2 = Char2 + 2
If (Byte2 And 32) > 0 Then Char2 = Char2 + 1
Char3 = Char3 + (Byte2 And 16)
Char3 = Char3 + (Byte2 And 8)
Char3 = Char3 + (Byte2 And 4)
Char3 = Char3 + (Byte2 And 2)
Char3 = Char3 + (Byte2 And 1)
tmpMfg = Chr(Char1 + 64) & Chr(Char2 + 64) & Chr(Char3 + 64)
Dim tmpEDIDMajorVer, tmpEDIDRev As Integer
tmpEDIDMajorVer = Asc(Encoding.[Default].GetString(bObj, &H12, 1))
tmpEDIDRev = Asc(Encoding.[Default].GetString(bObj, &H13, 1))
tmpVer = Chr(48 + tmpEDIDMajorVer) & "." & Chr(48 + tmpEDIDRev)
Dim tmpEDIDDev1, tmpEDIDDev2 As String
tmpEDIDDev1 = Hex(Asc(Encoding.[Default].GetString(bObj, &HA, 1)))
tmpEDIDDev2 = Hex(Asc(Encoding.[Default].GetString(bObj, &HB, 1)))
If Len(tmpEDIDDev1) = 1 Then tmpEDIDDev1 = "0" & tmpEDIDDev1
If Len(tmpEDIDDev2) = 1 Then tmpEDIDDev2 = "0" & tmpEDIDDev2
tmpDev = tmpEDIDDev2 & tmpEDIDDev1
'Search the Keys
For Each sDesc As String In sDescriptor
If sDesc.Contains(sSerFind) Then
sSerial = sDesc.Substring(4).Replace(vbNullChar, "").Trim()
End If
If sDesc.Contains(sModFind) Then
sModel = sDesc.Substring(4).Replace(vbNullChar, "").Trim()
End If
Next
End If
If Not String.IsNullOrEmpty(sPNPID & sSerFind & sModel & sMonitorID) Then
sReturn.Add({sMonitorID, sModel, sPNPID, tmpDev, tmpVer, tmpMfg, iWeek, iYear, sSerial})
End If
End If
End If
Next
End If
Next
End If
Return sReturn
End Function
【讨论】: