2010-04-19 9 views
6

Das folgende Codebeispiel verwendet, um mir Windows-ID vor, aber jetzt funktioniert es nicht, und gibt leere Zeichenfolge zurück, weiß nicht warum.Registrierung ReadString-Methode funktioniert nicht in Windows 7 in Delphi 7

function GetWindowsID: string; 
    var 
    Registry: TRegistry; 
    str:string; 
    begin 
    Registry := TRegistry.Create(KEY_WRITE); 
    try 
     Registry.Lazywrite := false; 
     Registry.RootKey := HKEY_LOCAL_MACHINE; 
    // Registry.RootKey := HKEY_CURRENT_USER; 
     if CheckForWinNT = true then 
     Begin 
     if not Registry.OpenKeyReadOnly('\Software\Microsoft\Windows NT\CurrentVersion') then showmessagE('cant open'); 
     end 
     else 
     Registry.OpenKeyReadOnly('\Software\Microsoft\Windows\CurrentVersion'); 
     str := Registry.ReadString('ProductId'); 
     result:=str; 
     Registry.CloseKey; 
    finally 
     Registry.Free; 
    end; // try..finally 
    end; 

Jeder kann helfen?

Antwort

23

Das liegt daran, dass der virtualisierte Schlüssel '\ Software \ Wow6432Node \ Microsoft \ Windows NT \ CurrentVersion \' das Element 'ProductID' nicht enthält.

Ändern Sie den Code der TRegistry Instanz mit

Registry := TRegistry.Create(KEY_WRITE OR KEY_WOW64_64KEY); 

wo KEY_WOW64_64KEY = $ 0100 zu erstellen. Das wird Ihnen das erwartete Ergebnis geben.

Alternativ verwenden DSiWin32 und rufen

DSiReadRegistry('\Software\Microsoft\Windows NT\CurrentVersion', 
    'ProductID', '', HKEY_LOCAL_MACHINE, KEY_QUERY_VALUE OR KEY_WOW64_64KEY); 
+0

Nützliche Informationen haben. Ich hatte noch nichts von DSiWin32 gehört. Wie ist es besser/unterscheidet sich von ähnlichen Routinen in der Jedi-Bibliothek? –

1

Ich würde sagen, dass dies von UAC verursacht wird - versuchen Sie, als Administrator zu starten!

Wenn es funktioniert, wenn sie als Administrator gestartet, dann müssen Sie Ihre Leseanforderung nur Lesemodus zu verwenden, ändern (nicht am Schreibtisch zu mo so nicht mehr genau, wie Sie das tun)

edit:

0

Versuchen Sie es manuell mit RegEdit zu lesen. Möglicherweise erhalten Sie aufgrund eines Berechtigungsproblems "Zugriff verweigert". In diesem Fall sehen Sie sich Ihr Level an und wie Sie darauf zugreifen.

1

Sie sollten dies mit: Mit dieser

-2

Ausführung wird nicht verhindern TRegistry.Create(KEY_ENUMERATE_SUB_KEYS); Fenster sieben UAC ich es glauben, weil

str := Registry.ReadString('ProductId'); 

tut keine Ausnahme auslösen, wenn es keine ProductId gibt. Meiner ehrlichen Meinung nach ist das ein Fehler in Delphi.

+0

ist es der Winapi. Es soll Configs zurückgeben. Wenn vorhanden, gibt es den Wert zurück, wenn nicht der Standardwert vorhanden ist. – Firo

+0

ist es kein Fehler. es ist ein Windows-Verhalten wie oben – Jonesome

3

Es gibt nützliches Verfahren Key Register in einem 32-Bit und 64-Bit lesen enviroment.First zu sehen, welches System Sie

Type TTypWin32Or64 = (Bit32,Bit64); 
var TypWin32Or64 :TTypWin32Or64; 

Procedure TypeOS(var TypWin32Or64:TTypWin32Or64) ; 
    if DirectoryExists('c:\Windows\SysWOW64') 
    then TypWin32Or64:=Bit64 
    else TypWin32Or64:=Bit32; 

    Procedure for looking Key or Create it in a Registry 
    procedure TForm1.ReadKeyFromRegister(TypWin32Or64:TTypWin32Or64; 
         TypeKey:Longword; {at once symbol HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER} 
         PathToKey:string; 
         TypeValueRead :Integer; //at once symbols as REG_SZ -- string key , 
          //REG_DWORD A DWORD value, a 32-bit unsigned integer 
         NameValueToRead:string; 
         var ValueStrReaded:Ansistring; //is used if it is key string 
         var ValueByteReaded:Pchar; //is used if it is key Byte 
         ReadOnly:boolean); 
var 
    Reg  : TRegistry; 
    S_TStr : TStrings; 
    VersBios : string; 
    Pos0  : integer; 
    Key  : HKEY; 
    Value  : Array of Byte; 
    nValueLen : Integer; 
const KEY_WOW64_64KEY = $0100 ; 
begin 
    case TypWin32Or64 of 
    Bit32: Reg := TRegistry.Create; 
    Bit64:Reg := TRegistry.Create(KEY_WRITE OR KEY_WOW64_64KEY); 
    //use if if 64 bit enviroment Windows 
    end; 
try 
    { open key } 
    Reg.RootKey := TypeKey; 
    if ReadOnly 
    then Reg.OpenKeyReadOnly(PathToKey) 
     //not all key can be created or writed ie. ProductId(Serial Key) 
     // name Windows - especially in a 64 bit Windows XP , Win 7 
    else Reg.OpenKey(PathToKey, false); 
     //CreateKey=True--> if this key is not present will be created 
    case TypeValueRead of 
    REG_SZ: ValueStrReaded:=Reg.ReadString(NameValueToRead); 
    REG_BINARY : begin 
        nValueLen := Reg.GetDataSize(NameValueToRead); 
        ValueByteReaded:=Pchar(Reg.ReadBinaryData(NameValueToRead, PByte(Value), nValueLen)); 
       end; 
    REG_DWORD : begin 

       end; 
    REG_MULTI_SZ: begin 
        S_TStr := ReadMultirowKey(Reg,NameValueToRead); 
         /in a enviroment 64 bit not good work - better use  
         //procedure ReadREG_MULTI_SZ 
        VersBios:=S_TStr.Text; 
        Pos0:=Pos(#0,VersBios); 
        if Pos0 > 0 then 
         begin 
         delete(VersBios,Pos0,1); 
         insert(' ', VersBios,Pos0); 
         end; 
        VersBios := StringReplace(VersBios,#$D#$A, ' ' , [rfReplaceAll, rfIgnoreCase]); 
        ValueStrReaded:=VersBios; 
       end; 
     end; //case 
     Reg.CloseKey; 
    finally 
    Reg.Free; 
    end; 
end; 
{------------} 

Sample for reading system Key from Registry 
    Reading UsedWindowsVersion_Full 
    ReadKeyFromRegister(TypWin32Or64, {TypWin32Or64} 
        HKEY_LOCAL_MACHINE, {TypeKey:Longword;} 
        'SOFTWARE\Microsoft\Windows NT\CurrentVersion', {PathToKey:string;} 
          REG_SZ, {TypeValueRead :Integer; } 
          'BuildLabEx', {NameValueToRead:string;} 
          UsedWindowsVersion_Full, {ValueStrReaded:Ansistring;} 
          sPchar ,{ValueByteReaded:Pchar} 
          True {ReadOnly}); 
      {-----------------------} 

     For read ProductId(also called Product Key Windows) 
      ReadKeyFromRegister(TypWin32Or64, 
        HKEY_LOCAL_MACHINE, {TypeKey:Longword;} 
        'SOFTWARE\Microsoft\Windows NT\CurrentVersion', {PathToKey:string;} 
          REG_SZ, {TypeValueRead :Integer; } 
          'ProductId', {NameValueToRead:string;} 
          SerialKey, {ValueStrReaded:Ansistring;} 
          sPchar, {ValueByteReaded:Pchar} 
          True {ReadOnly}); 
      {------------------------} 
    For reading Product Name 
     ReadKeyFromRegister(TypWin32Or64, 
        HKEY_LOCAL_MACHINE, {TypeKey:Longword;} 
        'SOFTWARE\Microsoft\Windows NT\CurrentVersion', {PathToKey:string;} 
          REG_SZ, {TypeValueRead :Integer; } 
          'ProductName', {NameValueToRead:string;} 
          UsedWindowsName, {ValueStrReaded:Ansistring;} 
          sPchar ,{ValueByteReaded:Pchar} 
          True {ReadOnly}); 
      {-----------------------} 
    Procedure for look miltiline key as i.e Version Bios - also 64 envir. 

    procedure TForm1.ReadREG_MULTI_SZ(const CurrentKey: HKey; const 
            Subkey, ValueName: string; 
            Strings: TStrings; var ValueStrRead: String); 
     var 
     valueType: DWORD; 
     valueLen: DWORD; 
     p, buffer: PChar; 
     key: HKEY; 
     begin 
     Strings.Clear; 
      // open the specified key 
     if RegOpenKeyEx(CurrentKey, 
       PChar(Subkey), 
       0, KEY_READ, key) = ERROR_SUCCESS then 
      begin 
      // retrieve the type and data for a specified value name 
      SetLastError(RegQueryValueEx(key, 
      PChar(ValueName), 
      nil, 
      @valueType, 
      nil, 
      @valueLen)); 
      if GetLastError = ERROR_SUCCESS then 
       if valueType = REG_MULTI_SZ then 
        begin 
        GetMem(buffer, valueLen); 
        try 
        // receive the value's data (in an array). 
        RegQueryValueEx(key, 
            PChar(ValueName), 
            nil, 
            nil, 
            PBYTE(buffer), 
            @valueLen); 
        // Add values to stringlist 
        p := buffer; 
        while p^ <> #0 do 
         begin 
         Strings.Add(p); 
         Inc(p, lstrlen(p) + 1) 
         end 
        finally 
         ValueStrRead:=Strings.Text; 
         ValueStrRead:=StringReplace(ValueStrRead,#$D#$A, ' ' , [rfReplaceAll, rfIgnoreCase]); 
         FreeMem(buffer); 
        end 
        end 
       else 
       raise ERegistryException.Create('Stringlist expected') 
        else 
        raise ERegistryException.Create('Cannot Read MULTI_SZ Value/'); 
      end; 
     end; 
     {-----------}  
+0

ReadMultirowKey Funktion diskutiert wird oben im Code fehlt .. [code] Erhältlich bei http://www.sql.ru/forum/955383/readmultirowkey [/ code] –