Registro ReadString metodo non funziona in Windows 7 in Delphi 7

L’esempio di codice seguente viene utilizzato per restituire me windows id prima, ma adesso non funziona più, e restituisce una stringa vuota, non so perché.

  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;

Qualcuno può aiutarmi?

OriginaleL’autore Tofig Hasanov | 2010-04-19

6 Replies
  1. 23

    Che è perché virtualizzato chiave\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\’ non contiene il “ProductID’ elemento.

    Modificare il codice per creare il TRegistry istanza con

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

    dove KEY_WOW64_64KEY = $0100. Che vi darà i risultati sperati.

    In alternativa, utilizzare DSiWin32 e chiamare

    DSiReadRegistry('\Software\Microsoft\Windows NT\CurrentVersion', 
      'ProductID', '', HKEY_LOCAL_MACHINE, KEY_QUERY_VALUE OR KEY_WOW64_64KEY);
    Info utili. Io non avevo sentito parlare di DSiWin32. Come è meglio / diverso da simili routine di un Jedi libreria?

    OriginaleL’autore gabr

  2. 3

    Ci sono utile procedura per la lettura della Chiave del Registro a 32 bit e a 64 bit con l’ambiente.Prima guardate cosa avete

    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;
          { ----------- }     
    ReadMultirowKey manca una funzione nel codice sopra.. [codice] Disponibile su: sql.ru/forum/955383/readmultirowkey [/code]

    OriginaleL’autore sp9auv

  3. 1

    Direi che questo è causato da UAC – prova ad avviare come amministratore!

    Se funziona quando viene avviato come amministratore, allora avete bisogno di cambiare la vostra richiesta di lettura per utilizzare la modalità di sola lettura (non alla scrivania a mo non ricordo esattamente come si fanno)

    edit:

    function GetWindowsID: string; 
    var 
      Registry: TRegistry; 
      str:string; 
    begin 
      Registry := TRegistry.Create(KEY_READ); 
      try 
        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; 

    OriginaleL’autore Mark Robinson

  4. 1

    Si dovrebbe utilizzare questo:
    TRegistry.Create(KEY_ENUMERATE_SUB_KEYS);
    windows seven UAC non impedire l’esecuzione di questo

    OriginaleL’autore sam

  5. 0

    Provare a leggere manualmente utilizzando RegEdit. Si può ottenere un “Accesso Negato” a causa di un problema di autorizzazioni, nel qual caso occhiata al tuo livello e come vi si accede.

    OriginaleL’autore Brian Frost

  6. -2

    Credo sia perché

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

    non genera un’eccezione quando non c’è ProductId. A mio parere onesto, questo è un bug in Delphi.

    è il winapi. Esso è destinato a tornare configs. Quando presenti, restituisce il valore, se non presente, il valore di default.
    non è un bug. si tratta di un comportamento di windows, come discusso in precedenza

    OriginaleL’autore JamesBrown

Lascia un commento