Jump to content

Get Monitor Information


Recommended Posts

it's all in the EDID registry entry. The vbs I posted explains where the info is within that 256 byte EDID. I will try to translate the remainder of the vbs script within the next week.

Lar.

Larry, that would be great!!!

I think it could be a great thing for all, who make asset...

Link to comment
Share on other sites

  • Replies 57
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

I did a rebuild of archrival's code without using WMI:

; Retrieve Monitor Model and Serial
; 13 November 2005 by Geert (NL)
; used parts made by archrival (http://www.autoitscript.com/forum/index.php?showtopic=11136)

; Collect EDID strings for all active monitors
$iCounterEDID = 0
Dim $asEDID[1]

$iCounterMonitorName = 1
Do
    $sMonitorName = RegEnumKey("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY", $iCounterMonitorName)
    If $sMonitorName <> "" Then
        $iCounterMonitorCode = 1
        Do
           ; Search 'monitor code' - 5&3aba5caf&0&10000080&01&00
            $sMonitorCode = RegEnumKey("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $sMonitorName, $iCounterMonitorCode)
           ; Search Control folder - When available, the active monitor is found
            $iCounterMonitorControlFolder = 1
            Do
                $sMonitorControlFolder = RegEnumKey("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $sMonitorName & "\" & $sMonitorCode, $iCounterMonitorControlFolder)
                If $sMonitorControlFolder == "Control" Then; Active monitor found!
                    $sMonitorEDIDRead = RegRead("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $sMonitorName & "\" & $sMonitorCode & "\Device Parameters", "EDID")
                    If $sMonitorEDIDRead <> "" Then
                        $sMonitorEDID = $sMonitorEDIDRead
                        $iCounterEDID = $iCounterEDID + 1
                        $asEDID[0] = $iCounterEDID
                        ReDim $asEDID[UBound($asEDID) + 1]
                        $asEDID[UBound($asEDID) - 1] = $sMonitorEDID; Add found EDID string to Array
                    EndIf
                EndIf
                $iCounterMonitorControlFolder = $iCounterMonitorControlFolder + 1; Increase counter to search for next folder
            Until $sMonitorControlFolder == ""
            $iCounterMonitorCode = $iCounterMonitorCode + 1; Increase counter to search for next 'monitor code' folder
        Until $sMonitorCode == ""
    EndIf
    $iCounterMonitorName = $iCounterMonitorName + 1; Increase counter to search for next monitor
Until $sMonitorName == ""


; Decrypt collected EDID strings - Thanks archrival
For $k = 1 To $asEDID[0]
    $sMonEDID = $asEDID[$k]
    If $sMonEDID <> "" Then
        $j = 0
        Dim $edidarray[StringLen($sMonEDID) ]
        $edidarray[0]= (StringLen($sMonEDID) / 2) + 1
        For $i = 1 To StringLen($sMonEDID) Step 2
            $j = $j + 1
            $edidarray[$j] = Dec(StringMid($sMonEDID, $i, 2))
        Next
        $ser = StringStripWS(_FindMonitorSerial(), 1 + 2)
        $name = StringStripWS(_FindMonitorName(), 1 + 2)
    Else
        $ser = ""
        $name = ""
    EndIf
    
    MsgBox(64, "Monitor " & $k, "MonitorSerial: " & $ser & @CRLF & "MonitorName: " & $name);Show MonitorSerial & MonitorName: no info? -> Your using a notebook right!
Next

; Functions

Func _FindMonitorSerial(); Thanks archrival
    $sernumstr = ""
    $sernum = 0
    For $i = 1 To (UBound($edidarray) / 2) - 4
        If $edidarray[$i] = "0" And $edidarray[$i + 1] = "0" And $edidarray[$i + 2] = "0" And $edidarray[$i + 3] = "255" And $edidarray[$i + 4] = "0" Then
            $sernum = $i + 4
        EndIf
    Next
    If $sernum <> 0 Then
        $endstr = 0
        $sernumstr = ""
        For $i = 1 To 13
            If $edidarray[$sernum + $i] = "10" Then
                $endstr = 1
            Else
                If $endstr = 0 Then
                    $sernumstr = $sernumstr & Chr($edidarray[$sernum + $i])
                EndIf
            EndIf
        Next
    Else
        $sernumstr = ""
    EndIf
    Return $sernumstr
EndFunc  ;==>_FindMonitorSerial

Func _FindMonitorName(); Thanks archrival
    $name = 0
    For $i = 1 To (UBound($edidarray) / 2) - 4
        If $edidarray[$i] = "0" And $edidarray[$i + 1] = "0" And $edidarray[$i + 2] = "252" And $edidarray[$i + 3] = "0" Then
            $name = $i + 3
        EndIf
    Next
    If $name <> 0 Then
        $endstr = 0
        $namestr = ""
        For $i = 1 To 13
            If $edidarray[$name + $i] = "10" Then
                $endstr = 1
            Else
                If $endstr = 0 Then
                    $namestr = $namestr & Chr($edidarray[$name + $i])
                EndIf
            EndIf
        Next
    Else
        $namestr = ""
    EndIf
    Return $namestr
EndFunc  ;==>_FindMonitorName
Link to comment
Share on other sites

Very nice work! However, I only get the serial number. Here's what the message box shows. I don't understand why it doesn't show the text "Monitor Name:" even if there is no monitor name?

---------------------------

Monitor 1

---------------------------

MonitorSerial: 0301059084

---------------------------

OK

---------------------------

FOUND IT!

Replace msgbox line with this one:

MsgBox(64, "Monitor " & $k, "MonitorSerial: " & StringStripCR($ser) & @LF & "MonitorName: " & $name);Show MonitorSerial & MonitorName: no info? -> Your using a notebook right!

There was a CR already in the variable $ser that is removed by stringstripcr...

Edited by jefhal
...by the way, it's pronounced: "JIF"... Bob Berry --- inventor of the GIF format
Link to comment
Share on other sites

Its showing serial number of monitor attached to local PC.. Waht about to get serial number of PC attached to network...

As long as you have read access to the remote registry, it's simple.

For example with no error checking what so ever:

; Retrieve Monitor Model and Serial
; 13 November 2005 by Geert (NL)
; used parts made by archrival (http://www.autoitscript.com/forum/index.php?showtopic=11136)

; Collect EDID strings for all active monitors
$iCounterEDID = 0
Dim $asEDID[1]

$Computer = InputBox("Computer Name", "Enter Computer Name", @ComputerName)

$iCounterMonitorName = 1
Do
    $sMonitorName = RegEnumKey("\\" & $Computer & "\HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY", $iCounterMonitorName)
    If $sMonitorName <> "" Then
        $iCounterMonitorCode = 1
        Do
          ; Search 'monitor code' - 5&3aba5caf&0&10000080&01&00
            $sMonitorCode = RegEnumKey("\\" & $Computer & "\HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $sMonitorName, $iCounterMonitorCode)
          ; Search Control folder - When available, the active monitor is found
            $iCounterMonitorControlFolder = 1
            Do
                $sMonitorControlFolder = RegEnumKey("\\" & $Computer & "\HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $sMonitorName & "\" & $sMonitorCode, $iCounterMonitorControlFolder)
                If $sMonitorControlFolder == "Control" Then; Active monitor found!
                    $sMonitorEDIDRead = RegRead("\\" & $Computer & "\HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $sMonitorName & "\" & $sMonitorCode & "\Device Parameters", "EDID")
                    If $sMonitorEDIDRead <> "" Then
                        $sMonitorEDID = $sMonitorEDIDRead
                        $iCounterEDID = $iCounterEDID + 1
                        $asEDID[0] = $iCounterEDID
                        ReDim $asEDID[UBound($asEDID) + 1]
                        $asEDID[UBound($asEDID) - 1] = $sMonitorEDID; Add found EDID string to Array
                    EndIf
                EndIf
                $iCounterMonitorControlFolder = $iCounterMonitorControlFolder + 1; Increase counter to search for next folder
            Until $sMonitorControlFolder == ""
            $iCounterMonitorCode = $iCounterMonitorCode + 1; Increase counter to search for next 'monitor code' folder
        Until $sMonitorCode == ""
    EndIf
    $iCounterMonitorName = $iCounterMonitorName + 1; Increase counter to search for next monitor
Until $sMonitorName == ""


; Decrypt collected EDID strings - Thanks archrival
For $k = 1 To $asEDID[0]
    $sMonEDID = $asEDID[$k]
    If $sMonEDID <> "" Then
        $j = 0
        Dim $edidarray[StringLen($sMonEDID) ]
        $edidarray[0]= (StringLen($sMonEDID) / 2) + 1
        For $i = 1 To StringLen($sMonEDID) Step 2
            $j = $j + 1
            $edidarray[$j] = Dec(StringMid($sMonEDID, $i, 2))
        Next
        $ser = StringStripWS(_FindMonitorSerial(), 1 + 2)
        $name = StringStripWS(_FindMonitorName(), 1 + 2)
    Else
        $ser = ""
        $name = ""
    EndIf
    
    MsgBox(64, "Monitor " & $k, "MonitorSerial: " & $ser & @CRLF & "MonitorName: " & $name);Show MonitorSerial & MonitorName: no info? -> Your using a notebook right!
Next

; Functions

Func _FindMonitorSerial(); Thanks archrival
    $sernumstr = ""
    $sernum = 0
    For $i = 1 To (UBound($edidarray) / 2) - 4
        If $edidarray[$i] = "0" And $edidarray[$i + 1] = "0" And $edidarray[$i + 2] = "0" And $edidarray[$i + 3] = "255" And $edidarray[$i + 4] = "0" Then
            $sernum = $i + 4
        EndIf
    Next
    If $sernum <> 0 Then
        $endstr = 0
        $sernumstr = ""
        For $i = 1 To 13
            If $edidarray[$sernum + $i] = "10" Then
                $endstr = 1
            Else
                If $endstr = 0 Then
                    $sernumstr = $sernumstr & Chr($edidarray[$sernum + $i])
                EndIf
            EndIf
        Next
    Else
        $sernumstr = ""
    EndIf
    Return $sernumstr
EndFunc ;==>_FindMonitorSerial

Func _FindMonitorName(); Thanks archrival
    $name = 0
    For $i = 1 To (UBound($edidarray) / 2) - 4
        If $edidarray[$i] = "0" And $edidarray[$i + 1] = "0" And $edidarray[$i + 2] = "252" And $edidarray[$i + 3] = "0" Then
            $name = $i + 3
        EndIf
    Next
    If $name <> 0 Then
        $endstr = 0
        $namestr = ""
        For $i = 1 To 13
            If $edidarray[$name + $i] = "10" Then
                $endstr = 1
            Else
                If $endstr = 0 Then
                    $namestr = $namestr & Chr($edidarray[$name + $i])
                EndIf
            EndIf
        Next
    Else
        $namestr = ""
    EndIf
    Return $namestr
EndFunc ;==>_FindMonitorName

That's just quick and dirty...

Edited by archrival
Link to comment
Share on other sites

Its showing serial number of monitor attached to local PC.. Waht about to get serial number of PC attached to network...

By the way, if you don't mind my asking, why would you need the serial number of the monitor? For service and repair?
...by the way, it's pronounced: "JIF"... Bob Berry --- inventor of the GIF format
Link to comment
Share on other sites

  • 2 years later...

I'm sorry to bring up an old thread, but this is exactly what I am looking for, however it does not work. I think it has something to do with the way it goes through the registry in the newer version of AutoIT. I am using AutoIT v3.2.12.1. Originally if I run the script it asks for the computer name and then just runs forever. I believe what is happening is it gets caught in an endless loop at the third DO loop. If right before it ends you input

MsgBox(0, "$sMonitorControlFolder", $sMonitorControlFolder)

I get the following messages:

Box1: Device Parameters

Box2: LogConf

Box3: No more data is available.

At this point you will continue to get what the third box said until you kill the script in another way. I have been looking at other functions people have written to scan the registry, but I would much rather this script work since it returns what i am looking for.

I have been using AutoIT randomly for projects and finally have given myself a decent sized one that goes beyond the scope I have learned, and I just sometimes have a hard time figuring out someone else's code.

Also I should mention I am referring to Geert's Post #22 as the script I was trying to use.

Edited by archgriffin

"Human kind cannot gain anything without first giving something in return, to obtain; something of equal value must be lost."The Help File is truly your friend.

Link to comment
Share on other sites

@archgriffin

see how this works, I can't test it for multiple monitors,

but it finds a single monitor fine

;Retrieve Monitor Model and Serial
;13 November 2005 by Geert (NL)
;used parts made by archrival (http://www.autoitscript.com/forum/index.php?showtopic=11136)
;Edited by rover 18 June 2008

;Collect EDID strings for all active monitors
#AutoIt3Wrapper_Au3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
Opt("MustDeclareVars", 1)

; ConsoleWrites slow a script if not needed
Global $Debug = True ; change to False or comment out/remove ConsoleWrite() lines if debugging to console not needed

Global $iCounterEDID = 0
Global $asEDID[1], $edidarray[1], $error1, $error2, $error3
Global $iCounterMonitorName = 1, $iCounterMonitorCode, $iCounterMonitorControlFolder
Global $sMonitorName, $sMonitorCode, $sMonitorControlFolder, $sMonitorEDIDRead, $ser, $name, $j

Do
    $sMonitorName = RegEnumKey("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY", $iCounterMonitorName)
    $error1 = @error
    If $Debug Then ConsoleWrite(@CRLF & '@@ Debug(' & @ScriptLineNumber & ') : $sMonitorName = ' & _
    StringStripWS($sMonitorName, 2) & @CRLF & '>Error code: ' & $error1 & @CRLF)
    If $sMonitorName <> "" Then
        $iCounterMonitorCode = 1
        Do
            ; Search 'monitor code' - e.g. 5&3aba5caf&0&10000080&01&00
            $sMonitorCode = RegEnumKey("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & _
            $sMonitorName, $iCounterMonitorCode)
            $error2 = @error
            If $Debug Then ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sMonitorCode = ' & _
            StringStripWS($sMonitorCode, 2) & @CRLF & '>Error code: ' & $error2 & @CRLF)
            ; Search Control folder - When available, the active monitor is found
            $iCounterMonitorControlFolder = 1
            
            Do
                $sMonitorControlFolder = RegEnumKey("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & _
                        $sMonitorName & "\" & $sMonitorCode, $iCounterMonitorControlFolder)
                $error3 = @error
                If $Debug Then ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sMonitorControlFolder = ' & _
                        StringStripWS($sMonitorControlFolder, 2) & @CRLF & '>Error code: ' & $error3 & @CRLF)
                If $sMonitorControlFolder == "Control" Then; Active monitor found!

                    Switch RegEnumVal("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $sMonitorName & _
                        "\" & $sMonitorCode & "\Device Parameters", 1)
                        Case "EDID"
                            $sMonitorEDIDRead = RegRead("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & _
                                    $sMonitorName & "\" & $sMonitorCode & "\Device Parameters", "EDID")
                            If $sMonitorEDIDRead <> "" Then
                                $iCounterEDID += 1
                                $asEDID[0] = $iCounterEDID
                                ReDim $asEDID[UBound($asEDID) + 1]
                                $asEDID[UBound($asEDID) - 1] = $sMonitorEDIDRead; Add found EDID string to Array
                            EndIf
                        Case "BAD_EDID"
                            $iCounterEDID += 1
                            $asEDID[0] = $iCounterEDID
                            ReDim $asEDID[UBound($asEDID) + 1]
                            $asEDID[UBound($asEDID) - 1] = "BAD_EDID"; Add BAD_EDID string to Array
                        Case Else
                    EndSwitch
                EndIf
                $iCounterMonitorControlFolder += 1; Increase counter to search for next folder
            Until $error3 <> 0
            $iCounterMonitorCode += 1; Increase counter to search for next 'monitor code' folder
        Until $error2 <> 0
    EndIf
    $iCounterMonitorName += 1; Increase counter to search for next monitor
Until $error1 <> 0

; Decrypt collected EDID strings - Thanks archrival
For $k = 1 To $asEDID[0]
    Switch $asEDID[$k]
        Case ""
            $ser = ""
            $name = ""
        Case "BAD_EDID"
            $ser = "BAD_EDID"
            $name = "BAD_EDID"
        Case Else
            $j = 0
            Dim $edidarray[StringLen($asEDID[$k])]
            $edidarray[0] = (StringLen($asEDID[$k]) / 2) + 1
            For $i = 1 To StringLen($asEDID[$k]) Step 2
                $j += 1
                $edidarray[$j] = Dec(StringMid($asEDID[$k], $i, 2))
            Next
            $ser = StringStripWS(_FindMonitorSerial(), 1 + 2)
            $name = StringStripWS(_FindMonitorName(), 1 + 2)
    EndSwitch

    ;Show MonitorSerial & MonitorName: no info? -> Your using a notebook right!
    MsgBox(64, "Monitor " & $k, "MonitorSerial: " & @TAB & _
    $ser & @CRLF & "MonitorName: " & @TAB & $name)
Next

#region - Functions
Func _FindMonitorSerial(); Thanks archrival
    Local $sernumstr = "", $sernum = 0, $endstr
    For $i = 1 To (UBound($edidarray) / 2) - 4
        If $edidarray[$i] = "0" And $edidarray[$i + 1] = "0" And $edidarray[$i + 2] = "0" _
            And $edidarray[$i + 3] = "255" And $edidarray[$i + 4] = "0" Then
            $sernum = $i + 4
        EndIf
    Next
    If $sernum <> 0 Then
        $endstr = 0
        For $i = 1 To 13
            If $edidarray[$sernum + $i] = "10" Then
                $endstr = 1
            Else
                If $endstr = 0 Then
                    $sernumstr &= Chr($edidarray[$sernum + $i])
                EndIf
            EndIf
        Next
    EndIf
    Return $sernumstr
EndFunc   ;==>_FindMonitorSerial

Func _FindMonitorName(); Thanks archrival
    Local $n = 0, $namestr = "", $endstr
    For $i = 1 To (UBound($edidarray) / 2) - 4
        If $edidarray[$i] = "0" And $edidarray[$i + 1] = "0" And _
            $edidarray[$i + 2] = "252" And $edidarray[$i + 3] = "0" Then
            $n = $i + 3
        EndIf
    Next
    If $n <> 0 Then
        $endstr = 0
        For $i = 1 To 13
            If $edidarray[$n + $i] = "10" Then
                $endstr = 1
            Else
                If $endstr = 0 Then
                    $namestr &= Chr($edidarray[$n + $i])
                EndIf
            EndIf
        Next
    EndIf
    Return $namestr
EndFunc   ;==>_FindMonitorName
#endregion
Edited by rover

I see fascists...

Link to comment
Share on other sites

That does indeed seem to work! Thank you very much. It appears you changed quite a bit of it though, which is fine with me, but if you have the time could you explain at least some how you figured out what to change. Anything I can do to learn more of this would be great.

Although I am not worried about the multiple monitor part, the only test I could do is on a laptop using an external screen as a secondary. I am just putting this here as reference for others. This laptop is often used with a projector, and it has been used with at least three different ones so that might be confusing it. When I ran this it was only connected to a single DELL LCD screen as it's secondary. The laptop is also a D630.

Monitor 1

Serial: BAD_EDID

Name: BAD_EDID

Monitor 2

Serial: BAD_EDID

Name: BAD_EDID

Monitor 3 (the connected external monitor)

Serial: Correct

Name: Correct

Monitor 4

Serial: blank

Name: blank

Anyways thank you again rover you are awesome!

"Human kind cannot gain anything without first giving something in return, to obtain; something of equal value must be lost."The Help File is truly your friend.

Link to comment
Share on other sites

@archgriffin

That does indeed seem to work! Thank you very much.

your welcome

It appears you changed quite a bit of it though,

which is fine with me, but if you have the time could you explain at least some how you figured out what to change.

the original script was using the blank string return from RegEnumKey() to exit from the nested Do loops

instead of using the error return set by RegEnumKey()

however it never exits the loops because of a returned error message string

That script dates to 2005. RegEnumKey() in that AutoIt version must have returned a blank string

if the key instance was out of range (no more keys).

RegEnumKey() in recent versions of AutoIt return a message as well as set error.

from helpfile RegEnumKey():

Success: Returns the requested subkey name..

Failure: Returns an error message string and sets the @error flag:

1 if unable to open requested key

2 if unable to open requested main key

3 if unable to remote connect to the registry

-1 if unable to retrieve requested subkey (key instance out of range)

adding a ConsoleWrite() in original script at line 22

@@ Debug(23) : $sMonitorControlFolder = No more data is available. ; never exits loop due to message string

>Error code: -1 ; indicates key instance out of range

the other changes involved addition of code to check for a BAD_EDID entry.

that way there is a least an error message if the find serial and name functions fail

removed a redundant variable $sMonitorEDID

compacted some of the code

Line 28 of original code:

$iCounterEDID = $iCounterEDID + 1

same as:

$iCounterEDID += 1

etc.:

$namestr = $namestr & Chr($edidarray[$name + $i])

same as:

$namestr &= Chr($edidarray[$n + $i])

changed functions to have Local variables and eliminated Global duplicate variable name usage.

$name was used Globally for strings then in a function for integer.

When I ran this it was only connected to a single DELL LCD screen as it's secondary.

In regards to the 4 message boxes you get:

That would indicate more than one 'control' key in the extra monitor entries

in the "HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" reg key

look at this line: If $sMonitorControlFolder == "Control" Then; Active monitor found!

on a multiple monitor system there would be more than one current 'Active' monitor.

(I only get one monitor entry with my old Matrox dual monitor card with two monitors).

only BAD_EDID or EDID keys with a string that also have the active monitor 'Control' key are returned by the script.

the blank message box return indicates an EDID entry without any serial or monitor info in the string, perhaps earlier EDID version,

or a damaged string, display driver error when EDID was originally written to reg, or that info not included in the monitor EDID,

or info location does not match pattern script searches for.

Read And Parse Monitor EDID Information... ( Vbscript )

http://cwashington.netreach.net/depo/view....ptType=vbscript

'The next difficulty is that all monitors are stored here not just the one currently plugged in.

'So, if you ever switched monitors the old one(s) will still be in the registry.

'You can tell which monitor(s) are active because they will have a sub-key named "Control"

http://www.lavalys.com/forum/lofiversion/i....php/t1829.html

Windows reads EDID data from video card using DDC at Windows startup.

For that you need a DDC-capable video card + a DDC capable video driver

+ a DDC capable monitor + a DDC capable video connector cable.

my BAD_EDID entries are from originally using an HD15 M To F cable with an adapter on the end for M to F

(used 21' Sony monitor came without a second input cable (HD15 M to M), so I used an adapter with the extension cable.

(missing pins in the adapter or extension cable for DDC support)

had to manually install monitor at the time using inf files, It wasn't detected by PnP.

and installed as 'Default Monitor'.

I deleted all the old monitor reg keys and swapped the good HD15 cable to that machine and ran 'Scan for hardware changes'

in Device manager to update from the Monitor via DDC.

Edited by rover

I see fascists...

Link to comment
Share on other sites

revised version with

ManuDate and EDID version

Edit: take a look at this free for individual users utility from EnTech

http://www.entechtaiwan.com/util/moninfo.shtm

It reads from the monitor directly without using the questionable data in the registry.

a much better solution as you can run it from a commandline and save the results to a file.

; Retrieve Monitor Model and Serial
; 13 November 2005 by Geert (NL)
; used parts made by archrival (http://www.autoitscript.com/forum/index.php?showtopic=11136)
; Edited/upgraded by rover 20 June 2008

; Collect EDID strings for all active monitors

;Links
;http://en.wikipedia.org/wiki/Extended_display_identification_data
;http://www.lavalys.com/forum/lofiversion/index.php/t1829.html
;http://cwashington.netreach.net/depo/view.asp?Index=1087&ScriptType=vbscript

#AutoIt3Wrapper_Au3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
Opt("MustDeclareVars", 1)

; ConsoleWrites slow a script if not needed
Global $bDebug = True ; change to False or comment out/remove ConsoleWrite() lines if debugging to console not needed

Global $bDisplayAll = False ; if false only 'Active' monitors (reg entries with 'Control' key) with EDID info reported
; 'Active' monitors with no reported EDID data(serial, name, date) are ignored

Global $asEDID[1][2] = [[0, 0]]
Global $iCounterEDID = 0, $sResults
Global $edidarray[1], $error1, $error2, $error3
Global $iCounterMonitorName = 1, $iCounterMonitorCode, $iCounterMonitorControlFolder
Global $sMonitorName, $sMonitorCode, $sMonitorControlFolder, $sMonitorEDIDRead
Global $ser, $name, $j, $sManuDate, $sEDIDVer

Do
    $sMonitorName = RegEnumKey("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY", $iCounterMonitorName)
    $error1 = @error
    If $bDebug Then ConsoleWrite(@CRLF & '@@ Debug(' & @ScriptLineNumber & ') : $sMonitorName = ' & _
            StringStripWS($sMonitorName, 2) & @CRLF & '>Error code: ' & $error1 & @CRLF)
    If $sMonitorName <> "" Then
        $iCounterMonitorCode = 1
        Do
            ; Search 'monitor code' - e.g. 5&3aba5caf&0&10000080&01&00
            $sMonitorCode = RegEnumKey("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & _
                    $sMonitorName, $iCounterMonitorCode)
            $error2 = @error
            If $bDebug Then ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sMonitorCode = ' & _
                    StringStripWS($sMonitorCode, 2) & @CRLF & '>Error code: ' & $error2 & @CRLF)
            ; Search Control folder - When available, the active monitor is found
            $iCounterMonitorControlFolder = 1
            Do
                $sMonitorControlFolder = RegEnumKey("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & _
                        $sMonitorName & "\" & $sMonitorCode, $iCounterMonitorControlFolder)
                $error3 = @error
                If $bDebug Then ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sMonitorControlFolder = ' & _
                        StringStripWS($sMonitorControlFolder, 2) & @CRLF & '>Error code: ' & $error3 & @CRLF)
                If $sMonitorControlFolder == "Control" Then; Active monitor found!
                    Switch RegEnumVal("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $sMonitorName & _
                            "\" & $sMonitorCode & "\Device Parameters", 1)
                        Case "EDID"
                            $sMonitorEDIDRead = RegRead("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & _
                                    $sMonitorName & "\" & $sMonitorCode & "\Device Parameters", "EDID")
                            If $bDebug Then ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sMonitorEDIDRead = ' & _
                                    $sMonitorEDIDRead & @CRLF & '>Error code: ' & @error & @CRLF)
                            If $sMonitorEDIDRead <> "" And Not @error Then
                                $iCounterEDID += 1
                                $asEDID[0][0] = $iCounterEDID
                                ReDim $asEDID[UBound($asEDID) + 1][2]
                                $asEDID[UBound($asEDID) - 1][0] = $sMonitorEDIDRead; Add found EDID string to Array
                                $asEDID[UBound($asEDID) - 1][1] = $sMonitorName
                            EndIf
                        Case "BAD_EDID"
                            $iCounterEDID += 1
                            $asEDID[0][0] = $iCounterEDID
                            ReDim $asEDID[UBound($asEDID) + 1][2]
                            $asEDID[UBound($asEDID) - 1][0] = "BAD_EDID"; Add BAD_EDID string to Array
                            $asEDID[UBound($asEDID) - 1][1] = $sMonitorName
                    EndSwitch
                EndIf
                $iCounterMonitorControlFolder += 1; Increase counter to search for next folder
            Until $error3 <> 0
            $iCounterMonitorCode += 1; Increase counter to search for next 'monitor code' folder
        Until $error2 <> 0
    EndIf
    $iCounterMonitorName += 1; Increase counter to search for next monitor
Until $error1 <> 0

; Extract info from collected EDID strings - Thanks archrival
If $asEDID[0][0] Then
    For $k = 1 To $asEDID[0][0]
        Switch $asEDID[$k][0]
            Case "BAD_EDID"
                If Not $bDisplayAll Then ContinueLoop
                $ser = "BAD_EDID"
                $name = "BAD_EDID"
            Case Else
                $j = 0
                ReDim $edidarray[StringLen($asEDID[$k][0])]
                $edidarray[0] = (StringLen($asEDID[$k][0]) / 2) + 1
                For $i = 1 To StringLen($asEDID[$k][0]) Step 2
                    $j += 1
                    $edidarray[$j] = Dec(StringMid($asEDID[$k][0], $i, 2))
                Next
                $ser = StringStripWS(_FindMonitorSerial($edidarray), 1 + 2)
                $name = StringStripWS(_FindMonitorName($edidarray), 1 + 2)
                If $name <> "Not Found" Then
                    $sManuDate = StringStripWS(_FindMonitorManuDate($asEDID[$k][0]), 1 + 2)
                    $sEDIDVer = StringStripWS(_FindMonitorEDIDVer($asEDID[$k][0]), 1 + 2)
                Else
                    $sManuDate = ""
                    $sEDIDVer = ""
                EndIf
                If Not $bDisplayAll Then
                    If $name = "Not Found" Then ContinueLoop
                EndIf
        EndSwitch

        $sResults &= @CRLF & "Monitor #" & $k & @CRLF & "VESA Monitor ID" & @TAB & $asEDID[$k][1] & @CRLF & _
                "Serial: " & @TAB & @TAB & $ser & @CRLF & "Name: " & @TAB & @TAB & $name & @CRLF & _
                "ManuDate: " & @TAB & $sManuDate & @CRLF & "EDID: " & @TAB & @TAB & $sEDIDVer & @CRLF
    Next
Else
    ; No EDID or BAD_EDID entries found
    $sResults = "No Monitors Found"
EndIf

;Show MonitorSerial & MonitorName: no info? -> Your using a notebook right!
MsgBox(64, "Active Monitor EDID Info", $sResults)
Exit

#Region - Functions
Func _FindMonitorSerial(ByRef $aArray); Thanks archrival
    If Not IsArray($aArray) Then Return
    Local $sSernumstr = "", $iSernum = 0, $iEndstr = 0
    For $i = 1 To (UBound($aArray) / 2) - 4
        If $aArray[$i] = "0" And $aArray[$i + 1] = "0" And $aArray[$i + 2] = "0" _
                And $aArray[$i + 3] = "255" And $aArray[$i + 4] = "0" Then
            $iSernum = $i + 4
        EndIf
    Next
    If $iSernum Then
        For $i = 1 To 13
            If $aArray[$iSernum + $i] = "10" Then
                $iEndstr = 1
            ElseIf Not $iEndstr Then
                $sSernumstr &= Chr($aArray[$iSernum + $i])
            EndIf
        Next
    Else
        Return "Not Found"
    EndIf
    Return $sSernumstr
EndFunc   ;==>_FindMonitorSerial

Func _FindMonitorName(ByRef $aArray); Thanks archrival
    If Not IsArray($aArray) Then Return
    Local $n = 0, $sNamestr = "", $iEndstr = 0
    For $i = 1 To (UBound($aArray) / 2) - 4
        If $aArray[$i] = "0" And $aArray[$i + 1] = "0" And _
                $aArray[$i + 2] = "252" And $aArray[$i + 3] = "0" Then
            $n = $i + 3
        EndIf
    Next
    If $n Then
        For $i = 1 To 13
            If $aArray[$n + $i] = "10" Then
                $iEndstr = 1
            ElseIf Not $iEndstr Then
                $sNamestr &= Chr($aArray[$n + $i])
            EndIf
        Next
    Else
        Return "Not Found"
    EndIf
    Return $sNamestr
EndFunc   ;==>_FindMonitorName
#EndRegion - Functions

Func _FindMonitorManuDate(ByRef $sEDID)
    Local $wk, $yr
    $wk = Dec(StringMid($sEDID, 33, 2)) ; 10h BYTE week number of manufacture
    $yr = Dec(StringMid($sEDID, 35, 2)) + 1990 ; 11h BYTE manufacture year - 1990
    If $wk = 0 Or $wk > 52 Or $yr < 2000 Or $yr > @YEAR Then
        Return ""
    EndIf
    Return "Week " & $wk & "/" & $yr
EndFunc   ;==>_FindMonitorManuDate

Func _FindMonitorEDIDVer(ByRef $sEDID)
    Local $iEDIDVer, $iEDIDRev
    $iEDIDVer = Dec(StringMid($sEDID, 37, 2)) ; 12h BYTE EDID version
    $iEDIDRev = Dec(StringMid($sEDID, 39, 2)) ; 13h BYTE EDID revision
    If $iEDIDVer < 1 Or $iEDIDRev < 2 Then
        Return ""
    EndIf
    Return "v" & $iEDIDVer & "." & $iEDIDRev
EndFunc   ;==>_FindMonitorEDIDVer
Edited by rover

I see fascists...

Link to comment
Share on other sites

I looked at the other program, and although it will certain return more data, the SN is really all I am looking for so I can make checking our database inventory a bit easier.

Also now with the explanation I will have more knowledge to troubleshoot further issues.

Thank you again for your responses, hopefully this helps others who go looking for the same information.

"Human kind cannot gain anything without first giving something in return, to obtain; something of equal value must be lost."The Help File is truly your friend.

Link to comment
Share on other sites

  • 2 months later...

Hi Guys!

I just started looking into AutoIt. So please excuse my newbie-status with -how-to-get-info for the scripts here.

I really like the last script stated here. I just have two questions for this:

1) we are using Dell monitors, the serial ist almost correct, just the first 3 digits are missing. How can I get these?

The total lengths of the dell monitor serials is 20 digits. Can I adopt that length to the script to get the full serial somehow?

2) also I would like to write that information to a file, either on the computer or the network.

How do I achieve that with AutoIt?

Thank you so much for your support.

Any information will be highly appreciated.

Markus

Edited by MarkusH
Link to comment
Share on other sites

Hi Guys!

I just started looking into AutoIt. So please excuse my newbie-status with -how-to-get-info for the scripts here.

I really like the last script stated here. I just have two questions for this:

1) we are using Dell monitors, the serial ist almost correct, just the first 3 digits are missing. How can I get these?

The total lengths of the dell monitor serials is 20 digits. Can I adopt that length to the script to get the full serial somehow?

2) also I would like to write that information to a file, either on the computer or the network.

How do I achieve that with AutoIt?

Thank you so much for your support.

Any information will be highly appreciated.

Markus

Hi MarkusH

Welcome to the forums and all that

I can see if its the last digits after 13 cut off because the original script

only gathers up to 13 digits.

I don't have the EDID spec in front of me

but I recall that industry isn't following the standard,

its possible the serial is stored differently in the registry EDID binary code

for you dell monitors.

if you meant last digits missing then replace this function in the above script

it will concatenate up to 20 numbers

the above example script follows EDID spec for location of the serial number,

at the end of the binary code.

search the forum for "EDID" for other posts on this topic.

another forum user is using 'DumpEDID", a program that reads the registry of remote pc's for same data

there are also WMI examples.

Func _FindMonitorSerial(ByRef $aArray); Thanks archrival
    If Not IsArray($aArray) Then Return
    Local $sSernumstr = "", $iSernum = 0, $iEndstr = 0
    For $i = 1 To (UBound($aArray) / 2) - 4
        If $aArray[$i] = "0" And $aArray[$i + 1] = "0" And $aArray[$i + 2] = "0" _
                And $aArray[$i + 3] = "255" And $aArray[$i + 4] = "0" Then
            $iSernum = $i + 4
        EndIf
    Next
    If $iSernum Then
        For $i = 1 To 20
            If $aArray[$iSernum + $i] = "10" Then
                $iEndstr = 1
            ElseIf Not $iEndstr Then
                $sSernumstr &= Chr($aArray[$iSernum + $i])
            EndIf
            ConsoleWrite('-$aArray[$i] = ' & $i & @crlf)
        Next
    Else
        Return "Not Found"
    EndIf
    Return $sSernumstr
EndFunc   ;==>_FindMonitorSerialoÝ÷ Ù«©mz¹Ú¶+Þ!ƦzêpØZ±Êâ¦Ûh"¶az趦"g§¶*'yا¶©¢ËZnÞ×âÛY¨+h®Ç(wµçZض«²)ß¡Ø«yËeÉúèØ^â¶ß¢»(é¨+h®jz[½éâ~Ø^ɪ޳­r¡÷쵩Ýo*hÁêí+,r¸©¶)Üç^²Ø^r¦z{l#
èµëh"¶¢YhÂêi¢Ëm¡ªÜ
â}ø§jËaxãðj˶+çpØmæ¢÷¬r¸©´bv}ýµº-êé¢ËbaÆ®¶­sc·âWG&7G2FRTDBæfòÂ6W&ÂçVÖ&W"æBÆÂÂBFR&Gv&RÆWfVÂF&V7FÇg&öÒFRÖöæF÷"fDD2À£·âæ÷Bg&öÒFR&Vv7G'vW&R×VÇFÆRöÆBÖöæF÷"VçG&W26âÆÂæF6FRFW&RFR7W'&VçB7FfRÖöæF÷"ࣷâ§W7B'VâÖöäæfòæWRâ67&BæB'6RFR&WGW&æVBfÆRf÷"FR6W&ÂçVÖ&W"æfòæBÖöFVÂæÖRà £·â6âfR×VÇFÆR6öçG&ö¶W2âFR&Vv7G'"öÆBÖöæF÷'2æòÆöævW"6öææV7FVBà £·â6òFBÖ¶W2BFff7VÇBFòFWFW&ÖæRFR7W'&VçB7FfRÖöæF÷"2FR67&B&VÆW2öâFW&R&Vær£·âb33´6öçG&öÂb33²&Vv7G'¶W2öæÇf÷"7W'&VçFÇ6öææV7FVB7FfRÖöæF÷'2à £·âFRÖWFöG2f÷"F&V7FÇ66W76ærFRÖöæF÷"TDBæfò2W6VBâÖöäæfòæWR£·â&Rf"Ö÷&RFff7VÇBFâF267&BÂæB&ö&&Çæ÷B÷76&ÆRâWFôBvF÷WBTDBÆ'&&W2æVVFVBà £·âFW&RÖ&RvöbÖ¶ærFR&÷fR67&B&BÖ÷&R&VÆ&ÆR'W6ærb33·2FòfW&g£·âFR7W'&VçBÖöæF÷"FVâ6ö×&RFò&Vv7G'TDBæfòâb33·fRöæÇB7W'6÷'vÆæ6RB6öFRf÷"FB÷76&ÆGâ £·â&W7B6öÇWFöâÖ&R6ö×÷6FRöbÆÂF&VRVÆVÖVçG2À£·âvWB&VræfòÀ£·âfW&g7W'&VçBÖöæF÷"vFb33·2ÂFòvWB6÷'&V7B&Vv7G'æfòf÷"ÖöæF÷"æÖRࣷâ6ö×&RFòÖöäæfòDD2&W7VÇG2&VræfòfW&fVB'FWFW&Öæær7W'&VçBÖöæF÷"vFb33·26â&RfÆÆ&6²`£·âVæ&ÆRFò&VBg&öÒÖöæF÷" £´ÖöäæfòæWP£µFR6fVG3 £²ÖöæF÷"ÂÖöæF÷"6&ÆRÂG&fW"ÂfBFFW"ÂWF2â×W7B&RDD26ö×ÆçBæB6öææV7FV@£²&Vv7G'TDBæfòv÷VÆFâb33·B&RFW&RbçöbFW6RfÆVBvVâÖöæF÷"v2ç7FÆÆVBâFRf'7BÆ6RࣲöæÇbFVfV7FfR6&ÆRöFFW"W6VBgFW"ÖöæF÷"ç7FÆÆVBÂv÷VÆBFR&VrVçG'&RW6VgVÂ2FRÖöæF÷"6÷VÆBæ÷B&R&VBà £²ÖöäæfòæWR&öw&Ò6&÷2Æ'&'×W7B&RWFòFFR2vVÆÂࣴg&öÒVåFV6f÷'V×3¢·W&ÅÖGG¢òöf÷'2æVçFV6FvâææWB÷fWwF÷2ç÷Ó#sBf×·6CÖ&##&fcCs&FVCF##&3f3vf²÷W&ÅÐ £³ÂÒ×V÷FVòÒÓãÆFb6Æ73ÒwV÷FWF÷såTõDRÂöFcãÆFb6Æ73ÒwV÷FVÖâsãÂÒ×V÷FV2ÒÓã²gV÷C´'&÷w6VBÕ4DâFòfæBFR$26ÆÆ&6·2÷RFƶVB&÷WB£¶æBf÷VæBæò÷FW"æf÷&ÖFöâ&÷WB$2Ô§0£¶÷FW"FâF÷6R6öææV7FVBFòFRfFVòÖæ÷'BG&fW £²v66VV×2Fò&Ræ66W76&ÆRVæÆW72b33¶Òw&Fær¶W&æVÂÖÖöFRG&fW#ò£´2ÖöææfòW6ærFW6R§2÷"2BW6ær6öÖWFærƶRFRWDW66R§0£¶âtD÷"6ÖÆ"Fò6öÖ×Væ6FRvFFRw&72FFW#ð £µFR$26ÆÆ&6·2Fò&WV&R¶W&æVÂÖöFRG&fW"À£¶æB¶W&æVÂÖöFRG&fW"2æ6ÇVFVBæBW6VB'ÖöäæfòÂ÷vW%7G&æB6ögDõ4Bࣴ'WBæöæRöbFW6R&öGV7G27GVÆÇW6RFRvæF÷w2$26ÆÆ&6·3 £·vBFWFò2W76VçFÆÇ&W&öGV6RFRÆ÷rÖÆWfVÂfFVò$õ2&÷WFæW2f÷"V6æBWfW'67W÷'FVBà £´öâFRÇW26FRÂFBÖ¶W2FVÒG&fW"æFWVæFVçBFWWfVâv÷&²â6fRÖöFRÀ£·v6FR2æ÷C²öâFRF÷vâ6FRÂBÖVç2V6æWr6&WV&W27V6Â7W÷'BæBVæ6RâWFFRâgV÷C³ÂÒÕV÷FTVæBÒÓãÂöFcãÂÒÕV÷FTTVæBÒÓà £¶W×ÆRöb'6ær&WGW&âg&öÒÖöäæfòæWP£·&WV&W2ÖöäæfòæWRæBÖöäæfòææâ67&FF £¶GG¢ò÷wwræVçFV6Fvâæ6öÒ÷WFÂöÖöææfòç6FУ´ÖöäæfòæWR÷2fÆVæÖP£¶b6fVBvFçGBWFVç6öâÂfÆR26fVBvFöæÇF&VRFV×2W"ÖöæF÷"ࣶb6fVB24Õ2fÆRvFæÖbWFVç6öâFVâgVÆÂ&W÷'B2&WGW&æVBࣴTDBÓ£´B4å#£µ4â ¢4WFôC5w&W%ôS46V6µõ&ÖWFW'3ÒÖB×r×r"×r2×rB×rR×r`¢6æ6ÇVFRfÇC´'&æS2fwC°¤÷BgV÷C´×W7DFV6Æ&Uf'2gV÷C²Â ¤vÆö&Âb33c·4fÆWGBÂb33c·4fÆVÖbÂb33c·5&örÂb33c·4æÂb33c¶WF6öFRÂb33c¶FF¤vÆö&Âb33c·4TDBÂb33c·5dU4BÂb33c·54âÂb33c·5&W7VÇG2Âb33c·4FF ¢b33c·4fÆWGBÒFV×F"fײgV÷C²b3#´ÖöæF÷$æfòçGBgV÷C²²2ÆæR&W÷'BVFB2ÂdU4BÂ6W&À¢b33c·4fÆVÖbÒFV×F"fײgV÷C²b3#´ÖöæF÷$æfòæÖbgV÷C²²gVÆÂ&'@¢b33c·5&örÒ67&DF"fײgV÷C²b3#´ÖöäæfòæWRgV÷C°¢b33c·4æÒ67&DF"fײgV÷C²b3#´ÖöäæfòæægV÷C° ¤bæ÷BfÆTW7G2b33c·5&öræBæ÷BfÆTW7G2b33c·4æFVà ×6t&÷ÂgV÷C´ÖöäæfògV÷C²ÂgV÷C´ÖöäæfòæWR÷"ÖöäæfòææÖ76ærg&öÒ67&BF&V7F÷'gV÷C² W@¤VæD` £´W×ÆRÒ×VÇFÖöæF÷"2ÆæR&W÷'@¢b33c¶WF6öFRÒ6VÆÄWV7WFUvB67&DF"fײgV÷C²b3#´ÖöäæfòæWRgV÷C²ÂgV÷C²÷2gV÷C²fײb33c·4fÆWGBÂ67&DF"£²b33c¶WF6öFRÒ'VåvB67&DF"fײgV÷C²b3#´ÖöäæfòæWR÷2gV÷C²fײb33c·4fÆWGBÂ67&DF"¥7vF6W'&÷  66R bæ÷BfÆTW7G2b33c·4fÆWGBFVâ6öçFçVT66P b33c·4FFÒfÆU&VBb33c·4fÆWGB bW'&÷"÷"æ÷B7G&ætÆVâb33c·4FFFVâ6öçFçVT66P 6öç6öÆUw&FR5$Äbfײb33c·4FFfײ5$Äb b33c¶FFÒ7G&æu7ÆBb33c·4FFÂ5$Äb bW'&÷"÷"æ÷B4'&b33c¶FFFVâ6öçFçVT66P f÷"b33c¶ÒFòb33c¶FF³Ð 7vF67G&ætÆVgBb33c¶FF²b33c¶ÒÂ" 66RgV÷C´TBgV÷C° b33c·4TDBÒ7G&æu7G&u2b33c¶FF²b33c¶ÒÂ2 66RgV÷C´BgV÷C° b33c·5dU4BÒ7G&æu7G&u2b33c¶FF²b33c¶ÒÂ2 66RgV÷Cµ4âgV÷C° ²÷FöæÆÇ7G&2öfbgV÷Cµ4âgV÷C²b÷RvçB6W&ÂöæÇà b33c·54âÒ7G&æu7G&u27G&æuG&ÔÆVgBb33c¶FF²b33c¶ÒÃ2Â2 6öç6öÆUw&FRgV÷C²ÒfwC²gV÷C²fײb33c·4TDBfײgV÷C²¢gV÷C²fײb33c·5dU4BfײgV÷C²¢gV÷C²fײgV÷Cµ4âgV÷C²fײb33c·54âfײ5$Äb b7G&ætÆVâb33c·54âfwC³ÒBæBæ÷B7G&æu&VtWb33c·54âÂb33²öb3#µr·ÅµõÒb33²ÂÂð æBæ÷B7G&æt4Çb33c·54âFVà b33c·5&W7VÇG2f׳Ò5$ÄbfײgV÷C´ÖöæF÷"2gV÷C²fײD"fײD"fײb33c·4TDBfײ5$Äbfײð gV÷CµdU4ÖöæF÷"BgV÷C²fײD"fײb33c·5dU4Bfײ5$Äbfײð gV÷Cµ6W&âgV÷C²fײD"fײD"fײb33c·54âfײ5$Ä` VÇ6P b33c·5&W7VÇG2f׳Ò5$ÄbfײgV÷C´ÖöæF÷"2gV÷C²fײD"fײD"fײb33c·4TDBfײ5$Äbfײð gV÷CµdU4ÖöæF÷"BgV÷C²fײD"fײb33c·5dU4Bfײ5$Äbfײð gV÷Cµ6W&âgV÷C²fײD"fײD"fײb33c·54âfײgV÷C²¢gV÷C²fײ5$Äbfײð gV÷C²¤Öæ÷B&R6W&Â2gV÷C²fײ5$Ä` VæD` 66RVÇ6P ´6öçFçVTÆö÷ VæE7vF6 æW@ ×6t&÷cBÂgV÷C´7FfRÖöæF÷"TDBæfògV÷C²Âb33c·5&W7VÇG2 66RVÇ6R ×6t&÷ÂgV÷C´ÖöäæfògV÷C²ÂgV÷C´W'&÷"vWGFær&W7VÇG2g&öÒÖöäæfòæWRgV÷C²¤VæE7vF6¤bfÆTW7G2b33c·4fÆWGBFVâfÆTFVÆWFRb33c·4fÆWGB¤bfÆTW7G2b33c·4fÆWGBFVâ×6t&÷ÂgV÷C´ÖöäæfògV÷C²ÂgV÷C´W'&÷"FVÆWFærFV×fÆRgV÷C²fײ5$Äbfײb33c·4fÆWGB   £´W×ÆR"gVÆÂ&'BöbÆÂFFFò'&¥'VåvB67&DF"fײgV÷C²b3#´ÖöäæfòæWR÷2gV÷C²fײb33c·4fÆVÖbÂ67&DF"Â5uôDR¥7vF6W'&÷  66R bæ÷BfÆTW7G2b33c·4fÆVÖbFVâ6öçFçVT66P b33c·4FFÒfÆU&VBb33c·4fÆVÖb bW'&÷"÷"æ÷B7G&ætÆVâb33c·4FFFVâ6öçFçVT66P 6öç6öÆUw&FR5$Äbfײb33c·4FFfײ5$Äb b33c¶FFÒ7G&æu7ÆBb33c·4FFÂ5$Äb bW'&÷"÷"æ÷B4'&b33c¶FFFVâ6öçFçVT66P ô'&F7Æb33c¶FFÂgV÷C´ÖöæF÷"TDBæfògV÷C²²gVÆÂ&W÷'@ 66RVÇ6R ×6t&÷ÂgV÷C´ÖöäæfògV÷C²ÂgV÷C´W'&÷"vWGFær&W7VÇG2g&öÒÖöäæfòæWRgV÷C²¤VæE7vF6¤fÆTFVÆWFRb33c·4fÆVÖb¤bfÆTW7G2b33c·4fÆVÖbFVà ×6t&÷ÂgV÷C´ÖöäæfògV÷C²ÂgV÷C´W'&÷"FVÆWFærFV×fÆRgV÷C²fײ5$Äbfײb33c·4fÆVÖb¤VæD`   £·â´W×ÆR"Ò6ævÆRÖöæF÷"&W÷'BÒFFFöæÂÖöæF÷'2æ÷B&W÷'FVBb&W6Vç@£·â'VåvB67&DF"fײgV÷C²b3#´ÖöäæfòæWR÷2gV÷C²fײb33c·4fÆWGBÂ67&DF"Â5uôDR£·â7vF6W'&÷ £·â66R£·âbæ÷BfÆTW7G2b33c·4fÆWGBFVâ6öçFçVT66P£·âb33c·4FFÒfÆU&VBb33c·4fÆWGB£·âbW'&÷"÷"æ÷B7G&ætÆVâb33c·4FFFVâ6öçFçVT66P£·â6öç6öÆUw&FR5$Äbfײb33c·4FFfײ5$Äb£·âb33c¶FFÒ7G&æu7ÆBb33c·4FFÂ5$Äb£·âbW'&÷"÷"æ÷B4'&b33c¶FFFVâ6öçFçVT66P£·âb33c·4FFÒ7G&æu7G&u27G&æuG&ÔÆVgBb33c¶FF³5ÒÃ2Â2£·â6öç6öÆUw&FRgV÷C²ÒfwC²gV÷C²fײb33c¶FF³ÒfײgV÷C²¢gV÷C²fײb33c¶FF³%ÒfײgV÷C²¢gV÷C²fײgV÷Cµ4âgV÷C²fײb33c·4FFfײ5$Äb£·âb7G&ætÆVâb33c·4FFfwC³ÒBæBæ÷B7G&æu&VtWb33c·4FFÂb33²öb3#µr·ÅµõÒb33²ÂÂð£·âæBæ÷B7G&æt4Çb33c·4FFFVࣷâ×6t&÷ÂgV÷C´ÖöæF÷"6W&Â2f÷"gV÷C²fײb33c¶FF³ÒfײgV÷C²dU4ÖöæF÷"gV÷C²fײb33c¶FF³%ÒÂb33c·4FF£·âVÇ6P£·â×6t&÷ÂgV÷C´ÖöæF÷"6W&Â2f÷"dU4ÖöæF÷"gV÷C²fײb33c¶FF³%ÒÂgV÷C´Öæ÷B&R6W&Â2gV÷C²fײb33c·4FF£·âVæD`£·âfÆTFVÆWFRb33c·4fÆWGB£·âbfÆTW7G2b33c·4fÆWGBFVࣷâ×6t&÷ÂgV÷C´ÖöäæfògV÷C²ÂgV÷C´W'&÷"FVÆWFærFV×fÆRgV÷C²fײ5$Äbfײb33c·4fÆWGB£·âVæD`£·â66RVÇ6R£·â×6t&÷ÂgV÷C´ÖöäæfògV÷C²ÂgV÷C´W'&÷"vWGFær&W7VÇG2g&öÒÖöäæfòæWRgV÷C²£·âVæE7vF6

I see fascists...

Link to comment
Share on other sites

Hey Rover,

that was a quick reply :)

But sadly the change in the script "For $i = 1 To 20" didn't work. AutoIt still can't pull the correct serial no. as expected.

Well, that would have been to easy, right? >_<

It seems like the Dell changed the Monitor's EDID somehow so AutoIt is not able to pull the full serial.

I will look for other sources, but thanks for your help :idiot:)!

Cheers,

markus

Link to comment
Share on other sites

Hey Rover,

that was a quick reply :)

But sadly the change in the script "For $i = 1 To 20" didn't work. AutoIt still can't pull the correct serial no. as expected.

Well, that would have been to easy, right? >_<

It seems like the Dell changed the Monitor's EDID somehow so AutoIt is not able to pull the full serial.

I will look for other sources, but thanks for your help :idiot:)!

Cheers,

markus

try running regedit and look at the data for 'Device Parameters' subkey below the 'Control' key named 'EDID'

HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\MONITORNAME

double click the entry and view the binary data

see if there is a serial just below the model name and is it preceded by '00 00 00 FF'

Edit: I see what the problem is, the first three letters/digits are left out as they are the same for that model

so you need to add them by matching the model name to a list of prefixes

read this page: http://www.myitforum.com/forums/fb.asp?m=161637

I could only view this through Google cache for some reason.

Edited by rover

I see fascists...

Link to comment
Share on other sites

  • 8 months later...

thank you for this rover!

ive been using this with some success...

can you or anyone else figure out a way i can get a more complete serial number? from what i could tell it only ouputs the last 8 characters (and the serial is in most cases what im seeing 14 characters)

revised version with

ManuDate and EDID version

Edit: take a look at this free for individual users utility from EnTech

http://www.entechtaiwan.com/util/moninfo.shtm

It reads from the monitor directly without using the questionable data in the registry.

a much better solution as you can run it from a commandline and save the results to a file.

; Retrieve Monitor Model and Serial
; 13 November 2005 by Geert (NL)
; used parts made by archrival (http://www.autoitscript.com/forum/index.php?showtopic=11136)
; Edited/upgraded by rover 20 June 2008

; Collect EDID strings for all active monitors

;Links
;http://en.wikipedia.org/wiki/Extended_display_identification_data
;http://www.lavalys.com/forum/lofiversion/index.php/t1829.html
;http://cwashington.netreach.net/depo/view.asp?Index=1087&ScriptType=vbscript

#AutoIt3Wrapper_Au3Check_Parameters= -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
Opt("MustDeclareVars", 1)

; ConsoleWrites slow a script if not needed
Global $bDebug = True ; change to False or comment out/remove ConsoleWrite() lines if debugging to console not needed

Global $bDisplayAll = False ; if false only 'Active' monitors (reg entries with 'Control' key) with EDID info reported
; 'Active' monitors with no reported EDID data(serial, name, date) are ignored

Global $asEDID[1][2] = [[0, 0]]
Global $iCounterEDID = 0, $sResults
Global $edidarray[1], $error1, $error2, $error3
Global $iCounterMonitorName = 1, $iCounterMonitorCode, $iCounterMonitorControlFolder
Global $sMonitorName, $sMonitorCode, $sMonitorControlFolder, $sMonitorEDIDRead
Global $ser, $name, $j, $sManuDate, $sEDIDVer

Do
    $sMonitorName = RegEnumKey("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY", $iCounterMonitorName)
    $error1 = @error
    If $bDebug Then ConsoleWrite(@CRLF & '@@ Debug(' & @ScriptLineNumber & ') : $sMonitorName = ' & _
            StringStripWS($sMonitorName, 2) & @CRLF & '>Error code: ' & $error1 & @CRLF)
    If $sMonitorName <> "" Then
        $iCounterMonitorCode = 1
        Do
            ; Search 'monitor code' - e.g. 5&3aba5caf&0&10000080&01&00
            $sMonitorCode = RegEnumKey("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & _
                    $sMonitorName, $iCounterMonitorCode)
            $error2 = @error
            If $bDebug Then ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sMonitorCode = ' & _
                    StringStripWS($sMonitorCode, 2) & @CRLF & '>Error code: ' & $error2 & @CRLF)
            ; Search Control folder - When available, the active monitor is found
            $iCounterMonitorControlFolder = 1
            Do
                $sMonitorControlFolder = RegEnumKey("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & _
                        $sMonitorName & "\" & $sMonitorCode, $iCounterMonitorControlFolder)
                $error3 = @error
                If $bDebug Then ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sMonitorControlFolder = ' & _
                        StringStripWS($sMonitorControlFolder, 2) & @CRLF & '>Error code: ' & $error3 & @CRLF)
                If $sMonitorControlFolder == "Control" Then; Active monitor found!
                    Switch RegEnumVal("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & $sMonitorName & _
                            "\" & $sMonitorCode & "\Device Parameters", 1)
                        Case "EDID"
                            $sMonitorEDIDRead = RegRead("HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\" & _
                                    $sMonitorName & "\" & $sMonitorCode & "\Device Parameters", "EDID")
                            If $bDebug Then ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $sMonitorEDIDRead = ' & _
                                    $sMonitorEDIDRead & @CRLF & '>Error code: ' & @error & @CRLF)
                            If $sMonitorEDIDRead <> "" And Not @error Then
                                $iCounterEDID += 1
                                $asEDID[0][0] = $iCounterEDID
                                ReDim $asEDID[UBound($asEDID) + 1][2]
                                $asEDID[UBound($asEDID) - 1][0] = $sMonitorEDIDRead; Add found EDID string to Array
                                $asEDID[UBound($asEDID) - 1][1] = $sMonitorName
                            EndIf
                        Case "BAD_EDID"
                            $iCounterEDID += 1
                            $asEDID[0][0] = $iCounterEDID
                            ReDim $asEDID[UBound($asEDID) + 1][2]
                            $asEDID[UBound($asEDID) - 1][0] = "BAD_EDID"; Add BAD_EDID string to Array
                            $asEDID[UBound($asEDID) - 1][1] = $sMonitorName
                    EndSwitch
                EndIf
                $iCounterMonitorControlFolder += 1; Increase counter to search for next folder
            Until $error3 <> 0
            $iCounterMonitorCode += 1; Increase counter to search for next 'monitor code' folder
        Until $error2 <> 0
    EndIf
    $iCounterMonitorName += 1; Increase counter to search for next monitor
Until $error1 <> 0

; Extract info from collected EDID strings - Thanks archrival
If $asEDID[0][0] Then
    For $k = 1 To $asEDID[0][0]
        Switch $asEDID[$k][0]
            Case "BAD_EDID"
                If Not $bDisplayAll Then ContinueLoop
                $ser = "BAD_EDID"
                $name = "BAD_EDID"
            Case Else
                $j = 0
                ReDim $edidarray[StringLen($asEDID[$k][0])]
                $edidarray[0] = (StringLen($asEDID[$k][0]) / 2) + 1
                For $i = 1 To StringLen($asEDID[$k][0]) Step 2
                    $j += 1
                    $edidarray[$j] = Dec(StringMid($asEDID[$k][0], $i, 2))
                Next
                $ser = StringStripWS(_FindMonitorSerial($edidarray), 1 + 2)
                $name = StringStripWS(_FindMonitorName($edidarray), 1 + 2)
                If $name <> "Not Found" Then
                    $sManuDate = StringStripWS(_FindMonitorManuDate($asEDID[$k][0]), 1 + 2)
                    $sEDIDVer = StringStripWS(_FindMonitorEDIDVer($asEDID[$k][0]), 1 + 2)
                Else
                    $sManuDate = ""
                    $sEDIDVer = ""
                EndIf
                If Not $bDisplayAll Then
                    If $name = "Not Found" Then ContinueLoop
                EndIf
        EndSwitch

        $sResults &= @CRLF & "Monitor #" & $k & @CRLF & "VESA Monitor ID" & @TAB & $asEDID[$k][1] & @CRLF & _
                "Serial: " & @TAB & @TAB & $ser & @CRLF & "Name: " & @TAB & @TAB & $name & @CRLF & _
                "ManuDate: " & @TAB & $sManuDate & @CRLF & "EDID: " & @TAB & @TAB & $sEDIDVer & @CRLF
    Next
Else
    ; No EDID or BAD_EDID entries found
    $sResults = "No Monitors Found"
EndIf

;Show MonitorSerial & MonitorName: no info? -> Your using a notebook right!
MsgBox(64, "Active Monitor EDID Info", $sResults)
Exit

#Region - Functions
Func _FindMonitorSerial(ByRef $aArray); Thanks archrival
    If Not IsArray($aArray) Then Return
    Local $sSernumstr = "", $iSernum = 0, $iEndstr = 0
    For $i = 1 To (UBound($aArray) / 2) - 4
        If $aArray[$i] = "0" And $aArray[$i + 1] = "0" And $aArray[$i + 2] = "0" _
                And $aArray[$i + 3] = "255" And $aArray[$i + 4] = "0" Then
            $iSernum = $i + 4
        EndIf
    Next
    If $iSernum Then
        For $i = 1 To 13
            If $aArray[$iSernum + $i] = "10" Then
                $iEndstr = 1
            ElseIf Not $iEndstr Then
                $sSernumstr &= Chr($aArray[$iSernum + $i])
            EndIf
        Next
    Else
        Return "Not Found"
    EndIf
    Return $sSernumstr
EndFunc   ;==>_FindMonitorSerial

Func _FindMonitorName(ByRef $aArray); Thanks archrival
    If Not IsArray($aArray) Then Return
    Local $n = 0, $sNamestr = "", $iEndstr = 0
    For $i = 1 To (UBound($aArray) / 2) - 4
        If $aArray[$i] = "0" And $aArray[$i + 1] = "0" And _
                $aArray[$i + 2] = "252" And $aArray[$i + 3] = "0" Then
            $n = $i + 3
        EndIf
    Next
    If $n Then
        For $i = 1 To 13
            If $aArray[$n + $i] = "10" Then
                $iEndstr = 1
            ElseIf Not $iEndstr Then
                $sNamestr &= Chr($aArray[$n + $i])
            EndIf
        Next
    Else
        Return "Not Found"
    EndIf
    Return $sNamestr
EndFunc   ;==>_FindMonitorName
#EndRegion - Functions

Func _FindMonitorManuDate(ByRef $sEDID)
    Local $wk, $yr
    $wk = Dec(StringMid($sEDID, 33, 2)) ; 10h BYTE week number of manufacture
    $yr = Dec(StringMid($sEDID, 35, 2)) + 1990 ; 11h BYTE manufacture year - 1990
    If $wk = 0 Or $wk > 52 Or $yr < 2000 Or $yr > @YEAR Then
        Return ""
    EndIf
    Return "Week " & $wk & "/" & $yr
EndFunc   ;==>_FindMonitorManuDate

Func _FindMonitorEDIDVer(ByRef $sEDID)
    Local $iEDIDVer, $iEDIDRev
    $iEDIDVer = Dec(StringMid($sEDID, 37, 2)) ; 12h BYTE EDID version
    $iEDIDRev = Dec(StringMid($sEDID, 39, 2)) ; 13h BYTE EDID revision
    If $iEDIDVer < 1 Or $iEDIDRev < 2 Then
        Return ""
    EndIf
    Return "v" & $iEDIDVer & "." & $iEDIDRev
EndFunc   ;==>_FindMonitorEDIDVer
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...