GetMonitor-Funktion testen

    • Offizieller Beitrag

    Ich habe gerade eine GetMonitor-Funktion für mein Computer-Info geschrieben, die auch mehrere Monitore erkennen kann.
    Bei mir funktioniert sie auch, aber da ich dabei jede Menge Einträge aus der Registry auslese, weiß ich nicht, ob sie überall funktioniert.
    Vielleicht könnt ihr mir mal helfen und die Funktion bei euch testen (keine Sorge, ich schreibe nichts in die Reg, es finden nur Lesezugriffe statt).
    Mich interessiert vor allem, ob mehrere Monitore einwandfrei erkannt werden. Aber auch sonst bin ich für Hinweise auf fehlerhafte Ausgaben dankbar.
    Das Testscript erstellt eine Textdatei mit den Ergebnissen. Vielleicht könntet ihr diese mitposten.

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    $aMonitor = _CI_GetMonitor()
    $hFile = FileOpen(@ScriptDir & '\!Monitor-Info.txt', 2)
    If $hFile <> -1 Then
    For $i = 0 To UBound($aMonitor) - 1
    $save = ''
    For $j = 0 To UBound($aMonitor, 2) - 1
    $save &= $aMonitor[$i][$j] & ' *** '
    Next
    FileWriteLine($hFile, $save)
    Next
    FileClose($hFile)
    EndIf
    _ArrayDisplay($aMonitor)

    [/autoit] [autoit][/autoit] [autoit]

    Func _CI_GetMonitor($strComputer = '.')
    Switch @OSVersion
    Case 'WIN_VISTA', 'WIN_7'
    Local $sX64 = '', $iCount, $sHKLM, $sTmp, $sMfg, $sDeviceDesc, $sDPMS, $sClassGUID, $sHardwareID
    If @OSArch <> 'X86' Then $sX64 = '64'
    $sHKLM = 'HKEY_LOCAL_MACHINE' & $sX64
    $iCount = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\services\monitor\Enum', 'Count')
    Local $aMonitor[$iCount + 1][6] = [['Hersteller:', 'Modell:', 'DPMS-Untersützung:', 'Position (x, y):', 'akt. Auflösung:', 'max. Auflösung:']]
    For $i = 1 To $iCount
    $sTmp = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\services\monitor\Enum', $i - 1)
    $sMfg = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\Enum\' & $sTmp, 'Mfg')
    $aMonitor[$i][0] = StringRegExpReplace($sMfg, '.+;(.+)', '$1')
    $sDeviceDesc = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\Enum\' & $sTmp, 'DeviceDesc')
    $aMonitor[$i][1] = StringRegExpReplace($sDeviceDesc, '.+;(.+)', '$1')
    $sDPMS = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\Enum\' & $sTmp & '\Device Parameters', 'DPMS')
    $aMonitor[$i][2] = StringMid('NeinJa', $sDPMS * 4 + 1, 4)
    $sClassGUID = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\Enum\' & $sTmp, 'ClassGUID')
    $sHardwareID = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\Enum\' & $sTmp, 'HardwareID')
    Local $iEnum = 0, $sTmpKey, $sMatchingDeviceId, $sConnectivity, $sRecent, $sMatchConfig, $j, $x, $y, $cx, $cy
    While True
    $sTmpKey = $sHKLM & '\SYSTEM\CurrentControlSet\Control\Class\' & $sClassGUID & '\' & StringRight('0000' & $iEnum, 4)
    $sMatchingDeviceId = RegRead($sTmpKey, 'MatchingDeviceId')
    If @error Then ExitLoop
    If $sMatchingDeviceId = $sHardwareID Then
    $aMonitor[$i][5] = StringReplace(RegRead($sTmpKey, 'MaxResolution'), ',', ' x ')
    $sConnectivity = RegEnumKey($sHKLM & '\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Connectivity', 1)
    $sRecent = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Connectivity\' & $sConnectivity, 'Recent')
    $j = 0
    Do
    $j += 1
    $sMatchConfig = RegEnumKey($sHKLM & '\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Configuration\', $j)
    Until StringInStr($sMatchConfig, $sRecent) Or (@error <> 0)
    $sTmp = $sHKLM & '\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Configuration\' & $sMatchConfig & '\' & StringRight('00' & $i - 1, 2)
    $x = Number(String(RegRead($sTmp, 'Position.cx')))
    If $x > 2 ^ 31 Then $x = -BitXOR($x, 0xffffffff)
    $y = Number(String(RegRead($sTmp, 'Position.cy')))
    If $y > 2 ^ 31 Then $y = -BitXOR($y, 0xffffffff)
    $cx = RegRead($sTmp, 'PrimSurfSize.cx')
    $cy = RegRead($sTmp, 'PrimSurfSize.cy')
    $aMonitor[$i][4] = $cx & ' x ' & $cy
    $aMonitor[$i][3] = $x & ', ' & $y
    ExitLoop
    EndIf
    $iEnum += 1
    WEnd
    Next
    Return $aMonitor
    Case Else
    Local $aReturn[2][8] = [[ _
    'Hersteller:', 'Modell:', 'Breite (Pixel):', 'Höhe (Pixel):', _
    'Pixel pro Inch (X):', 'Pixel pro Inch (Y):', 'Monitorgröße (ca.):', 'PNPDeviceID:']]
    Local $x = 0, $objWMIService, $colItems, $Output
    $objWMIService = ObjGet('winmgmts:\\' & $strComputer & '\root\cimv2')
    If Not IsObj($objWMIService) Then Return SetError(1, 0, 0)
    $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_DesktopMonitor', 'WQL', 0x30)
    If IsObj($colItems) Then
    For $objItem In $colItems
    $x += 1
    ReDim $aReturn[$x + 1][8]
    $aReturn[$x][0] = $objItem.MonitorManufacturer
    $aReturn[$x][1] = $objItem.Name
    $aReturn[$x][2] = $objItem.ScreenWidth
    $aReturn[$x][3] = $objItem.ScreenHeight
    $aReturn[$x][4] = $objItem.PixelsPerXLogicalInch
    $aReturn[$x][5] = $objItem.PixelsPerYLogicalInch
    $aReturn[$x][6] = Round($objItem.ScreenWidth / ($objItem.PixelsPerXLogicalInch / 2.54), 2) & _
    ' x ' & Round($objItem.ScreenHeight / ($objItem.PixelsPerYLogicalInch / 2.54), 2) & ' cm²'
    $aReturn[$x][7] = $objItem.PNPDeviceID
    Next
    EndIf
    Return $aReturn
    EndSwitch
    EndFunc ;==>_CI_GetMonitor

    [/autoit]
    • Offizieller Beitrag

    Hier mein Test:

    Getestet mit Win7 Ultimate64, Autoit Version 3.3.2.0.

  • welche autoit version hast du dafür verwendet??

    Bei mir kommen da amssenweise Fhler wenn ich das testen will

    Computers are like Airconditioning. They don´t work with open Windows.

    • Offizieller Beitrag

    Ja, ich benutze immer die aktuelle AutoIt-Version. :)
    Uh, da sind ja ein paar schlechte Beispiele dabei. Wie sind eure Monitore angeschlossen? DVI oder Analog?

    Hier mal die Ausgabe von meinen beiden Monitoren (Win7, 64Bit):
    autoit.de/wcf/attachment/7021/

    So hatte ich mir das eigentlich gedacht. :S

  • Hmm, ich schätze das es bei Xp einfach in nem Anderen Registry schlüsseln drinnen steht

    Also könntest du vllt die Betreibssystem version auslesen, und je nachdem was man hat, eben die daten aus dem richtigen registryschlüssel auslesen.

    Frag mich aber bitte nicht welcher das ist^^

    mfg

    Computers are like Airconditioning. They don´t work with open Windows.

  • Hmm hab grad mal in der registry nachgeschaut, aber nicht wirklich was gefunden

    Das einzige was ich gefunden habe ist das: HKEY_LOCAL_MACHINE\HARDWARE\VIDEO

    Da steht einiges drinnen über einige Geräte, kann aber nix damit anfangen (bzw weis ncit wie^^)

    mfg

    Computers are like Airconditioning. They don´t work with open Windows.

  • Son zufall, hab vor 2 Tagen selber an sowas gearbeitet, kam aber nicht sehr weit (Wusste nicht wie man rausbekommt ob der Monitor Primary oder Secondary ist)

    Hier ist mal mein Code, Erkannt werden alle Monitore die auch im Gerätemanager angezeigt werden

    Spoiler anzeigen
    [autoit]

    ;####################################################################
    ;#
    ;# Func _GetDisplays() ermittelt benutzte Monitore
    ;#
    ;# Rückgabewerte: Array[0][0] = Anzahl der Monitore = n
    ;# Array[n][0] = Hersteller
    ;# Array[n][1] = Modell
    ;# Array[n][2] = Maximale Auflösung X (Breite)
    ;# Array[n][3] = Maximale Auflösung Y (Höhe)
    ;# Array[n][4] = Treiberversion
    ;# Array[n][5] = Treiberdatum, Format: MM-DD-YYYY
    ;# Array[n][6] = *.inf-Datei des Treibers
    ;# Array[n][7] = *.inf-Sektion Treibers
    ;#
    ;# Autor: Bitboy
    ;####################################################################
    Func _GetDisplays()
    Local $i=1, $j=1, $counter=0, $enumkey1, $enumkey2, $retArray[64][8], $resArr, $temp
    While 1
    $enumkey1 = RegEnumKey("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY", $i)
    If @error <> 0 then ExitLoop

    [/autoit] [autoit][/autoit] [autoit]

    $j = 1
    While 1
    $enumkey2 = RegEnumKey("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $enumkey1, $j)
    If @error <> 0 then ExitLoop
    RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $enumkey1 & "\" & $enumkey2 & "\Control", "")
    If @error <> 1 Then
    $counter = $counter + 1
    $retArray[$counter][0] = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $enumkey1 & "\" & $enumkey2, "Mfg")
    $retArray[$counter][1] = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $enumkey1 & "\" & $enumkey2, "DeviceDesc")
    $temp = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $enumkey1 & "\" & $enumkey2, "Driver")
    $resArr = StringSplit(RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\" & $temp, "MaxResolution"), ",")
    $retArray[$counter][2] = $resArr[1]
    $retArray[$counter][3] = $resArr[2]
    $retArray[$counter][4] = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\" & $temp, "DriverVersion")
    $retArray[$counter][5] = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\" & $temp, "DriverDate")
    $retArray[$counter][6] = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\" & $temp, "InfPath")
    $retArray[$counter][7] = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\" & $temp, "InfSection")
    EndIf
    $j = $j + 1
    WEnd

    $i = $i + 1
    WEnd
    ReDim $retArray[$counter+1][8]
    $retArray[0][0] = $counter
    Return $retArray
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #include <array.au3>
    $test = _GetDisplays()
    _ArrayDisplay($test)

    [/autoit]

    Einmal editiert, zuletzt von Bitboy (21. Dezember 2009 um 13:20)

    • Offizieller Beitrag

    So, ich habe die Funktion für Vista & Win7 nochmal überarbeitet. Könnt ihr mal testen, ob das jetzt stimmt?

    Spoiler anzeigen
    [autoit]


    #include <Array.au3>
    $aMonitor = _CI_GetMonitor()
    _ArrayDisplay($aMonitor)

    [/autoit] [autoit][/autoit] [autoit]

    Func _CI_GetMonitor()
    Local $iCount, $sHKLM, $sTmp, $sMfg, $sDeviceDesc, $sDPMS, $sTmpKey, $sDriver, $x, $y, $xRes, $yRes
    $sHKLM = 'HKEY_LOCAL_MACHINE'
    If @OSArch <> 'X86' Then $sHKLM &= '64'
    Switch @OSVersion
    Case 'WIN_VISTA', 'WIN_7'
    $iCount = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\services\monitor\Enum', 'Count')
    Local $aMonitor[$iCount + 1][6] = [['Hersteller:', 'Modell:', 'DPMS-Untersützung:', 'Position (x, y):', 'akt. Auflösung:', 'max. Auflösung:']]
    For $i = 1 To $iCount
    $sTmp = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\services\monitor\Enum', $i - 1)
    $sMfg = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\Enum\' & $sTmp, 'Mfg')
    $aMonitor[$i][0] = StringRegExpReplace($sMfg, '.+;(.+)', '$1')
    $sDeviceDesc = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\Enum\' & $sTmp, 'DeviceDesc')
    $aMonitor[$i][1] = StringRegExpReplace($sDeviceDesc, '.+;(.+)', '$1')
    $sDPMS = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\Enum\' & $sTmp & '\Device Parameters', 'DPMS')
    $aMonitor[$i][2] = StringMid('NeinJa', $sDPMS * 4 + 1, 4)
    $sDriver = RegRead($sHKLM & '\SYSTEM\CurrentControlSet\Enum\' & $sTmp, 'Driver')
    $sTmpKey = $sHKLM & '\SYSTEM\CurrentControlSet\Control\Class\' & $sDriver
    $aMonitor[$i][5] = StringReplace(RegRead($sTmpKey, 'MaxResolution'), ',', ' x ')
    $sTmpKey = $sHKLM & '\SYSTEM\CurrentControlSet\Hardware Profiles\UnitedVideo\CONTROL\VIDEO'
    $sTmp = RegEnumKey($sTmpKey, 1)
    $sTmpKey &= '\' & $sTmp & '\' & StringRight('0000' & $i - 1, 4)
    $x = Number(String(RegRead($sTmpKey, 'Attach.RelativeX')))
    If $x > 2 ^ 31 Then $x = -BitXOR($x, 0xffffffff)
    $y = Number(String(RegRead($sTmpKey, 'Attach.RelativeY')))
    If $y > 2 ^ 31 Then $y = -BitXOR($y, 0xffffffff)
    $xRes = Number(String(RegRead($sTmpKey, 'DefaultSettings.XResolution')))
    $yRes = Number(String(RegRead($sTmpKey, 'DefaultSettings.YResolution')))
    $aMonitor[$i][3] = $x & ', ' & $y
    $aMonitor[$i][4] = $xRes & ' x ' & $yRes
    Next
    Return $aMonitor
    Case Else
    MsgBox(0,0, 'OS wird z.Zt. nicht unterstützt.')
    EndSwitch
    EndFunc ;==>_CI_GetMonitor

    [/autoit]


    Für WindowsXP finde ich einfach keinen Zusammenhang zwischen den Monitor-Hersteller-Angaben und den Monitor-Daten (Auflösung, etc.).
    Wenn mehrere Monitore vorhanden sind, weiß ich nicht, welche Daten zu welchem Monitor gehören. Das ist echt zum verzweifeln... ?(