2010-04-19 142 views
6

以下代碼示例用於返回我之前的Windows ID,但現在它不起作用,並返回空字符串,不知道爲什麼。註冊表ReadString方法在Delphi 7中無法在Windows 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; 

有人可以幫忙嗎?

回答

23

這是因爲虛擬化密鑰'\ Software \ Wow6432Node \ Microsoft \ Windows NT \ CurrentVersion \'不包含'ProductID'項目。

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

其中KEY_WOW64_64KEY = $ 0100修改代碼來創建TRegistry實例。這會給你預期的結果。

或者,使用DSiWin32並調用

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

有用的信息有用的程序。我沒有聽說過DSiWin32。它與Jedi庫中的類似例程有什麼更好/不同? – 2011-10-25 10:25:37

1

我想說這是由UAC造成的 - 試試以管理員身份啓動!

如果它工作時以管理員身份啓動,那麼你需要改變使用只讀模式的讀取請求(而不是在莫部門,以便可以不記得你到底如何做到這一點)

編輯:

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

嘗試使用RegEdit手動讀取它。由於權限問題,您可能會收到「拒絕訪問」,在這種情況下請查看您的級別以及訪問方式。

1

你應該使用這樣的: TRegistry.Create(KEY_ENUMERATE_SUB_KEYS); Windows 7的UAC不會阻止執行此

-2

我相信這是因爲

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

做當沒有ProductId時不會引發異常。我誠實地認爲,這是Delphi中的一個錯誤。

+0

這是winapi。它意味着返回配置。出現時,如果不存在默認值,則返回該值。 – Firo 2012-11-08 15:47:48

+0

這不是一個錯誤。它是一個如上所述的窗口行爲 – Jonesome 2013-07-25 18:36:55

3

有讀取密鑰寄存器在32位和64位enviroment.First看看你有什麼系統

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函數缺少上面的代碼.. [code] Available at http://www.sql.ru/forum/955383/readmultirowkey [/ code] – 2016-01-02 18:25:45

相關問題