Einzelnen Beitrag anzeigen

Mr8411s

Registriert seit: 7. Mai 2010
2 Beiträge
 
#23

Re: Monitor Seriennummer auslesen

  Alt 9. Mai 2010, 22:39
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;
  Mit Zitat antworten Zitat