Registry ReadString method is not working in Windows 7 in Delphi 7

前端 未结 6 470
感动是毒
感动是毒 2021-01-12 22:03

The following code sample used to return me windows id before, but now it doesn\'t work, and returns empty string, dunno why.

  function GetWindowsID: string         


        
相关标签:
6条回答
  • 2021-01-12 22:39

    Try reading it manually using RegEdit. You may get 'Access Denied' due to a permission issue, in which case look at your level and how you are accessing it.

    0 讨论(0)
  • 2021-01-12 22:43

    You should using this: TRegistry.Create(KEY_ENUMERATE_SUB_KEYS); windows seven UAC won't prevent executing this

    0 讨论(0)
  • 2021-01-12 22:48

    There are usefull procedure to read Key Register in a 32 bit and 64 bit enviroment.First look what system you have

    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 讨论(0)
  • 2021-01-12 22:50

    I'd say that this is caused by UAC - try starting as administrator!

    If it works when started as administrator, then you need to change your read request to use read only mode (not at desk at mo so can't remember exactly how you do that)

    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; 
    
    0 讨论(0)
  • 2021-01-12 22:54

    I believe it's because

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

    does not raise an exception when there is no ProductId. In my honest opinion, this is a bug in Delphi.

    0 讨论(0)
  • 2021-01-12 22:57

    That is because the virtualized key '\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\' doesn't contain the 'ProductID' item.

    Modify your code to create the TRegistry instance with

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

    where KEY_WOW64_64KEY = $0100. That will give you the expected result.

    Alternatively, use DSiWin32 and call

    DSiReadRegistry('\Software\Microsoft\Windows NT\CurrentVersion', 
      'ProductID', '', HKEY_LOCAL_MACHINE, KEY_QUERY_VALUE OR KEY_WOW64_64KEY);
    
    0 讨论(0)
提交回复
热议问题