Delphi-PRAXiS
Seite 3 von 3     123   

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)

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:22 Uhr.
Seite 3 von 3     123   

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