Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Monitor Seriennummer auslesen (https://www.delphipraxis.net/23913-monitor-seriennummer-auslesen.html)

bafoeg 11. Jun 2004 22:15


Monitor Seriennummer auslesen
 
Hallo & Mahlzeit zusammen,

ich bin auf der Suche nach einer Routine die mir hilft die Monitorseriennummer auszulesen, wenn diese nicht (!) in der Registry steht. Sozusagen aus dem Monitor selbst.

Gibt es dort eine Delphi Möglichkeit?

Gruss
Bafög

Tubos 12. Jun 2004 06:26

Re: Monitor Seriennummer auslesen
 
Ich glaube der Monitor ist rein passiv und kann keine Daten zum Computer übertragen.

edit: Deshalb kann die Seriennummer auch nicht in der Registry stehen.

Robert Marquardt 12. Jun 2004 07:09

Re: Monitor Seriennummer auslesen
 
Ich bezweifle auch das die Seriennummer woanders als auf einem Schildchen am Monitor steht.

bafoeg 12. Jun 2004 10:02

Re: Monitor Seriennummer auslesen
 
Sorry, da muss ich leider widersprechen, bei so gut wie jedem neueren Monitor ist die Ser# auslesbar.
Beispielhaft sind hier die Sony Monitore genannt. Beim drücken der "Menü" Taste >5Sek erscheint die Ser#, die Produktionswoche und das Jahr. Das läßt sich dann mit dem einen oder anderen Tool auslesen.

Daher meine Frage. Ich suche eine Methode dies in Delphi zu realisieren :mrgreen:

Bafög

Christian Seehase 12. Jun 2004 12:23

Re: Monitor Seriennummer auslesen
 
Moin Bafög,

erst einmal herzlich willkommen hier in der Delphi-PRAXiS.

Mir fällt dazu als erstes mal das Kürzel DDC (Display Data Channel) ein.
Über den können Daten vom Monitor ausgelesen werden, ansonsten könnte Windows ja auch die Monitore nicht automatisch erkennen.

Wenn Du die Daten mit Delphi auslesen willst, ginge das eventuell über die WMI Schnittstelle, denn, soweit ich weiss, ansonsten ginge es wohl nur mit einem Treiber, und der lässt sich mit Delphi mit normalen Mitteln nicht erstellen.

Ob es eventuell noch andere API Funktionen gibt, mit denen man die Daten auslesen kann weiss ich allerdings nicht.

Blinky 12. Jun 2004 12:25

Re: Monitor Seriennummer auslesen
 
also, unter Windwos 2000 findest du die Informationen (EDID) in der Registry unter HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\.

Dieser Registry Key wird bei jedem reboot des Betriebssystems neu eingelesen. Dort findest du alle jemals angeschlossenen Monitore mit ihren Seriennummern sofern sie dem Standard entsprechen :-)) und du keine Monitor Switchbox verwendest - sowie weitere Informationen wie Auflösung und Herstellungs-Kalenderwoche.

ich habe mich gerade letzten Monat mit dieser Problematik beschäftigt :wall:

Gruss
Blinky

Tubos 12. Jun 2004 12:27

Re: Monitor Seriennummer auslesen
 
Zitat:

Mir fällt dazu als erstes mal das Kürzel DDC (Display Data Channel) ein.
Über den können Daten vom Monitor ausgelesen werden, ansonsten könnte Windows ja auch die Monitore nicht automatisch erkennen.
echt?
cool, wieder was dazugelernt :D

bafoeg 13. Jun 2004 11:50

Re: Monitor Seriennummer auslesen
 
Code:
also, unter Windwos 2000 findest du die Informationen (EDID) in der Registry unter HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\.
Leider steht auch hier nicht die Ser# drin. Oder solle das der Binärwert unter "Device Parameters" sein????

Das über WMI auslesen, ist sicherlich auch eine Alternative. Hat da jemand Erfahrung?

Gruss
Bafög

Christian Seehase 13. Jun 2004 14:34

Re: Monitor Seriennummer auslesen
 
Moin Bafoeg,

da stellen sich mir zwei Fragen:
Unterstützt der Monitor denn überhaupt DDC?
Lässt sich die Seriennummer überhaupt aus dem Gerät auslesen?

bafoeg 13. Jun 2004 15:16

Re: Monitor Seriennummer auslesen
 
Zitat:

Unterstützt der Monitor denn überhaupt DDC?
Lässt sich die Seriennummer überhaupt aus dem Gerät auslesen?
Ja! Es ist ein Sony sdm-s73
Es gibt auch freeware tools die die Werte auslesen können. Auch von anderen Herstellern (z.B. Samsung)

Bafög

Blinky 14. Jun 2004 08:17

Re: Monitor Seriennummer auslesen
 
Hallo bafoeg, hallo erstmal zusammen :-)

dem ist genauso wie du vermutet hast.

Die EDID entspricht meines Wissens nach dem - was der Monitor via DDC beim Boot dem Betriebssystem mitteilt - (Danke Chris, waren fast zeitgleich).

Ein auslesen via WMI wäre die einfachste Methode, dies war jedoch in meinem Fall nicht möglich. Da sich bei unseren Maschinen auf diesem Key zusätzlich ein fehlerhafter Eintrag befindet, der sich nicht einfach so auf sichere Weise löschen lässt (bei der Anzahl von Maschienen) - habe ich diesen Lösungsweg gewählt (Die WMI Funktion lieferte immer einen Leeren Wert).

Durch ein auslesen direkt via DDC würde man wohl die aktuellesten Informationen kriegen, diese konnte ich jedoch nicht realisieren, aber wäre sicher sehr interessant.

Einfach wenn du eine Monitor Switchbox dazwischengeschaltet hast, liefert diese unter umständen das DDC Signal nicht weiter.

Falls es dir etwas weiterhilft, hier einen Link zu Microsoft "WMI\computer_system_hardware_classes"

http://msdn.microsoft.com/library/de...re_classes.asp

Gruss Blinky
als bisheriger nur Leser der "Delphi-Praxis" möchte ich mich mal bei allen hier bedanken, habe ich hier doch schon so mache Info und Hilfe entdeckt :-).

bafoeg 14. Jun 2004 22:56

Re: Monitor Seriennummer auslesen
 
Hallo zusammen!

ich werde versuchen DDC auszuprobieren.
Nur stelle ich mir dann die Frage, wie die div. Sharewaretools das auch während des laufenden Betriebes anstellen, und nicht nur beim booten :gruebel:

Wenn ich mir die MSDN Library durchsuche finde ich unter:

- Win32_VideoConfiguration
- Win32_DisplayConfiguration
- Win32_DisplayControllerConfiguration

Zwar schon einige Infos, aber leider keine, wie man die Serial auslesen kann...habe ich da was überlesen??

Bafög

bafoeg 17. Jun 2004 06:30

Re: Monitor Seriennummer auslesen
 
Hallo zusammen,

hier: Webpage Title
Gibts z.B. das Tool zum auslesen der Ser.

Bafög

scp 27. Jun 2004 01:25

Re: Monitor Seriennummer auslesen
 
Für alle, die sich für den EDID header interessieren, hier gibt es die Spezifikation. Der Header würde in Delphi also so aussehen:
Delphi-Quellcode:
type
  TEDIDHeader = record
    Padding : array[1..8] of Byte;
    VendorID : Word;  // bits 14 - 10 first letter (01h='A', 02h='B', etc.)
                        // bits 9 - 5 second letter
                        // bits 4 - 0 third letter
    ProductID : Word;
    SerialNo : DWord; // serial number or FFFFFFFFh
                        //   for "MAG", subtract 7000000 to get actual serial number
                        //   for "OQI", subtract 456150000
                        //   for "PHL", subtract ???
                        //   for "VSC", subtract 640000000
    ManufactureWeek : Byte;
    ManufactureYear : Byte; // manufacture year - 1990
    EDIDversion : Byte;
    EDIDrevision : Byte;
    VideoInputType : Byte;
    SizeHorizontal : Byte; // in cm
    SizeVertical  : Byte;   // in cm
    GammaFactor : Byte;    // gamma factor (gamma = 1.0 + factor/100, so max = 3.55)
    DPMSflags : Byte;
    ChromaXYgreenred : Byte;
    ChromaXYwhiteblue : Byte;
    ChromaXred  : Byte;
    ChromaYred  : Byte;
    ChromaXgreen : Byte;
    ChromaYgreen : Byte;
    ChromaXblue : Byte;
    ChromaYblue : Byte;
    ChromaXwhite : Byte;
    ChromaYwhite : Byte;
    EstablishedTimings1 : Byte;
    EstablishedTimings2 : Byte;
    ManufacturersReservedTiming : Byte;
    StandardTimingIdentification : array[1..8] Of Word;
    DetailedTimingDescription1 : array[1..18] Of Byte;
    DetailedTimingDescription2 : array[1..18] Of Byte;
    DetailedTimingDescription3 : array[1..18] Of Byte;
    DetailedTimingDescription4 : array[1..18] Of Byte;
    Unused : Byte;
    Checksum : Byte;
  end;
Jetzt muss man nur noch die Binärdaten aus der Registry auslesen und in eine Variable dieses Typs schleusen.

EDIT:
Es gibt mehrere Spezifikationen (1.0, 1.1, 1.2, 1.3 und 2.0) die leicht voneinander abweichen. Besonders zu beachten ist, das v2.0 aus 256 bytes besteht, daher immer nur die ersten 128 bytes kopieren oder ein Reserverd : array[1..128] Of Byte an den Header anhängen.

bafoeg 8. Jul 2004 18:28

Re: Monitor Seriennummer auslesen
 
cool danke! :-D

andy65 3. Dez 2004 16:35

Re: Monitor Seriennummer auslesen
 
Hallo

Ich kann die EDID Informationen aus der Registry auslesen. Es gelingt mir auch die rein numerischen Werte auszulesen. Wo ich aber im Moment überhaupt nicht weiter komme ist bei

Zitat:

VendorID : Word; // bits 14 - 10 first letter (01h='A', 02h='B', etc.)
// bits 9 - 5 second letter
// bits 4 - 0 third letter
ProductID : Word;
SerialNo : DWord; // serial number or FFFFFFFFh
// for "MAG", subtract 7000000 to get actual serial number
// for "OQI", subtract 456150000
// for "PHL", subtract ???
// for "VSC", subtract 640000000
Wie kann ich eine Word- oder DWord-variable in einen String umwandeln, so dass in diesem dann auch der Herrsteller oder die Seriennummer steht?

Gruss
Andy

supermuckl 3. Dez 2004 16:40

Re: Monitor Seriennummer auslesen
 
Herzlich Willkommen

Dword ist DoubleWord und das ist eine "Zahl"

Wie der Delphi OH zu entnehmen:

Type Range Format
Integer ?2147483648..2147483647 signed 32-bit
Cardinal 0..4294967295 unsigned 32-bit
Fundamental integer types include Shortint, Smallint, Longint, Int64, Byte, Word, and Longword.

Type Range Format
Shortint ?128..127 signed 8-bit
Smallint ?32768..32767 signed 16-bit
Longint ?2147483648..2147483647 signed 32-bit
Int64 ?2^63..2^63?1 signed 64-bit
Byte 0..255 unsigned 8-bit
Word 0..65535 unsigned 16-bit
Longword 0..4294967295 unsigned 32-bit

also einfach inttostr(variable als longword) und du hast deinen string

wenn das allerdings noch kodiert ist, dann musst du das noch umwandeln

andy65 4. Dez 2004 08:18

Re: Monitor Seriennummer auslesen
 
Hallo supermuckel

Ganz so einfach ist es leider nicht! wenn ich z.B. Das Feld VendorId nehme erhalte ich mit IntToStr 183 als Rückgabewert. Ich sollte aber 3 Zeichne, auf meinem PC 'SAM' für Samsung, zurückbekommen. Ich muss also diesen Wert irgendwie Bitweise auftrennen, damit ich an die einzelnen Zeichen komme und da fehlt mir im Moment der Lösungsweg.

Gruss
Andy

Nothine 4. Dez 2004 11:09

Re: Monitor Seriennummer auslesen
 
Delphi-Quellcode:
function _5BitsToChr(Vendor: Word): Char;
asm
  AND EAX,$1F
  ADD EAX,$41
end;

function GetVendorString(VendorID: Word): string;
begin
  SetLength(Result,3);
  Result := _5BitsToChr(VendorID shr $A) + //bits 14-10
            _5BitsToChr(VendorID shr $5) + //bits 9- 5
            _5BitsToChr(VendorID);        //bits 4- 0
end;
@andy65: für die von dir angegebenen 183 kommt allerdings 'AFX' raus :gruebel:

scp 24. Dez 2004 01:31

Re: Monitor Seriennummer auslesen
 
Kram aus....
Die Bytes müssen vorher verdreht werden, dann haut es hin.

Delphi-Quellcode:
function VendorLetters(vid : word) : String;
begin
  vid := ((vid and $00FF) shl 8) +
         ((vid and $FF00) shr 8);

  result := Chr(((vid and $7C00) shr 10) + $40) +
            Chr(((vid and $03E0) shr 5) + $40) +
            Chr(((vid and $001F)      ) + $40);
end;

Mr8411s 7. Mai 2010 22:35

Re: Monitor Seriennummer auslesen
 
Hi zusammen,

könnte mir bitte jemand auf die Sprünge helfen?

Ich muss für eine Anwendung Kalibrierungsinformationen für jeden einzelnen Monitor speichern. Damit das einen Sinn macht, muss das Programm alle angeschlossenen Monitore eindeutig identifizieren können. Die EDID-Variante gefällt mir zwar, aber ich komme in der Registry nicht bis zu dem betreffenden Datensatz durch. HKLM\...\DISPLAY ist klar, aber jetzt hab ich z. B. die Keys "AUO20EC", "NEC61BE" usw. und jeweils einen oder mehrere Subkeys à la "4&dbfd605&0&80871400&00&22", die dann unter "Device Parameters" die EDIDs enthalten.

Im Programm habe ich den Monitorindex aus TScreen zur Verfügung (und ggf. noch die Auflösung und was TScreen/TMonitor noch so alles zurückgeben). Wie bekomme ich anhand des Index heraus, in welche Subkeys ich schauen muss, um die EDID zu genau diesem Monitor zu bekommen?

Hab mir auch WMI und SetupAPI angeschaut, bin damit aber auch nicht weiter gekommen. Würde mich über ein kleines, treffendes Beispiel freuen. Danke :)

RWarnecke 8. Mai 2010 08:15

Re: Monitor Seriennummer auslesen
 
Zitat:

Zitat von Mr8411s
...Datensatz durch. HKLM\...\DISPLAY ist klar, aber jetzt hab ich z. B. die Keys "AUO20EC", "NEC61BE" usw. und jeweils einen oder mehrere Subkeys à la "4&dbfd605&0&80871400&00&22", die dann unter "Device Parameters" die EDIDs enthalten...

Vielleicht hilft Dir ja dieser Beitrag weiter.

Mr8411s 9. Mai 2010 22:39

Re: Monitor Seriennummer auslesen
 
Vielen Dank, das hat mir echt weiter geholfen. Zunächst hat es nicht funktioniert, weil die GetPnPDeviceID-Funktion mir nichts als "*PNP09FF" zurückgegeben hat (egal für welchen Monitor). Nach einer Erweiterung um noch eine temporäre Liste und einer Suche nach der passenden Driver-GUID\Nr. unter ...ENUM\DISPLAY\ hat es aber geklappt.

Meine Lösung, falls noch jemand dieses Problem damit hat:
(*) bedeutet: umbenannt wegen Konflikt mit anderen Deklarationen etc.
Nicht wundern, durch hin- und herprobieren (und durch eine Anpassung an meine Anwendung) haben sich u. a. auch einige Ausrichtungen und Feldnamen im Vergleich zum Originalcode geändert :)

Delphi-Quellcode:
function TDisplayInfo.GetPnPDeviceID: string;
var
  reg: TRegistry;
  DisDev,
  DisDevMon: TDisplayDevice2; // = TDisplayDevice incl. DeviceID & DeviceKey (*)
  tempkey,
  drv: string; // enthält eine Zeichenkette mit GUID und laufender Treibernummer, z. B.:
               // "{4D36E96E-E325-11CE-BFC1-08002BE10318}\0001"
  tempkeylist,
  tempsubkeylist: TStringList;
  i, j,
  ld: Integer; // Hilfsvariable zur Extraktion des GUID\DrvNr-Strings
begin
  // Initialisierung
  result := ''; // Sobald result nicht mehr leer ist, wird die Iteration abgebrochen, siehe (‡)
  tempkeylist := TStringList.Create;
  tempsubkeylist := TStringList.Create;
  tempkeylist.Clear;
  tempsubkeylist.Clear;
  reg := TRegistry.Create;
  reg.RootKey := HKEY_LOCAL_MACHINE;
  try
    DisDev.Size := SizeOf(TDisplayDevice2);
    DisDevMon.Size := SizeOf(TDisplayDevice2);

    // EnumDisplayDevices2 = EnumDisplayDevices mit TDisplayDevice2-Unterstützung (*)

    // Registry-Schlüssel des Monitors herausfinden
    if EnumDisplayDevices2(nil, fCurrDispIndex, DisDev, 0) then begin
      if DisDev.StateFlags = DISPLAY_DEVICE_MIRRORING_DRIVER
        then exit;
      while EnumDisplayDevices2(@DisDev.DeviceName, 0, DisDevMon, 0) do begin
        tempkey := DisDevMon.DeviceKey;
        if (DisDevMon.StateFlags <> DISPLAY_DEVICE_ACTIVE)
          then break;
      end;
    end else exit; // Wenn EnumDisplayDevices2 fehlschlägt, braucht auch der Rest nicht ausgeführt zu werden.

    // GUID\DrvNr extrahieren
    ld := LastDelimiter('{', tempkey);
    tempkey := copy(tempkey, ld, length(tempkey) - ld + 1); // jetzt enthält tempkey "{4D36E96E-...}\0001"

    if reg.OpenKeyReadOnly('SYSTEM\CurrentControlSet\Enum\DISPLAY\') then begin

      // alle direkten SubKeys aus der Registry holen
      reg.GetKeyNames(tempkeylist);
      reg.CloseKey; // sonst schlägt OpenKeyReadOnly fehl

      for i := 0 to tempkeylist.Count - 1 do begin
        if reg.OpenKeyReadOnly('SYSTEM\CurrentControlSet\Enum\DISPLAY\' + tempkeylist[i] + '\') then begin

          // alle direkten SubKeys aus der Registry holen
          reg.GetKeyNames(tempsubkeylist);
          reg.CloseKey; // sonst schlägt OpenKeyReadOnly fehl

          for j := 0 to tempsubkeylist.Count - 1 do begin
            if reg.OpenKeyReadOnly('SYSTEM\CurrentControlSet\Enum\DISPLAY\' + 
                                   tempkeylist[i] + '\' +             // Monitor "XYZ1234"
                                   tempsubkeylist[j] + '\') then     // PNP Key(?) "4&7af726e&..."
            begin
              drv := reg.ReadString('Driver');
              if drv = tempkey then begin
                result := tempkeylist[i] + '\' + tempsubkeylist[j];
                break; // (‡)
              end;
              reg.CloseKey;
            end;
          end;
          reg.CloseKey;
        end;
        if result <> '' // (‡)
          then break;
      end;
    end;
  finally
    reg.CloseKey;
    reg.Free;
    tempkeylist.Free;
    tempsubkeylist.Free;
  end;
end;

axellang 10. Mai 2010 20:06

Re: Monitor Seriennummer auslesen
 
Zitat:

Zitat von Mr8411s

Hab mir auch WMI und SetupAPI angeschaut, bin damit aber auch nicht weiter gekommen. Würde mich über ein kleines, treffendes Beispiel freuen. Danke :)

Hi,

um mit WMI vernünftig zu arbeiten, empfehle ich Dir als erstes das Tool Scriptomatic 2.0 von "The Scripting Guys" (Microsoft). Das ist eine ZIP-Exe die zwei Dateien entpackt. Die ScriptomaticV2.hta und die readme.doc.

Unter XP einfach die *.hta Datei staren und los gehts. Bei Vista oder 7even musst Du die *.hta als Admin ausführen damit es funktioniert! Hierzu musst Du zuerst das Command Prompt als Admin ausführen und darüber die *.hta Datei aufrufen. Die Anwendung ScriptomaticV2.hta, HTA steht für Hypertext Application, generiert Dir gleich den Code in VB, Perl, JScrip oder Python.

Dann lade Dir die WMI and SMART Components für Delphi herunter. Du musst nur die Units einbinden nichts installieren! Aber da ist eh ne Demo bei, die die Funktionalität gut erklärt.

<edit>

Fast hätte ich es vergessen, die WMI Klasse die Du benötigst heißt: Win32_DesktopMonitor. NameSpace: root\CIMV2

</edit>

Viel Spass

Axel

RWarnecke 10. Mai 2010 20:37

Re: Monitor Seriennummer auslesen
 
Hallo Axel,

mit der Klasse bekommst Du nur die hälfte an Infos wenn überhaupt. Die Seriennummer eines angeschlossenen Monitors ist nicht über WMI auslesbar.

axellang 11. Mai 2010 10:26

Re: Monitor Seriennummer auslesen
 
Zitat:

Zitat von RWarnecke
Hallo Axel,

mit der Klasse bekommst Du nur die hälfte an Infos wenn überhaupt. Die Seriennummer eines angeschlossenen Monitors ist nicht über WMI auslesbar.

Lieber RWarnecke,

na das ist ja fein. Bitte sage mir, was man noch herausfinden kann was die Klasse Win32_DektopMonitor nicht bereitstellt.

Gruß

Axel

RWarnecke 11. Mai 2010 11:03

Re: Monitor Seriennummer auslesen
 
Hallo Axel,

hast Du den Beitrag #14 gelesen ? Nicht alle diese Infos findest Du in der WMI-Klasse.

axellang 14. Mai 2010 15:18

Re: Monitor Seriennummer auslesen
 
Zitat:

Zitat von RWarnecke
Hallo Axel,

hast Du den Beitrag #14 gelesen ? Nicht alle diese Infos findest Du in der WMI-Klasse.

Sorry war auf Schulung...

Ja das ist richtig, will man alles muss man diesen Weg gehen.

Gruß

Axel


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:03 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz