2016-02-23 27 views
0

我想從註冊表項中獲取reg_binary作爲字符串。使用Tregistry類在delphi中讀取reg_binary作爲字符串

這是我的功能

function ReadBinString(key: string; AttrName: string): string; 
var 
ReadStr: TRegistry; 

begin 
// Result := ''; 
ReadStr := TRegistry.Create(KEY_WRITE OR KEY_WOW64_64KEY); 
ReadStr.RootKey := HKEY_LOCAL_MACHINE; 

    if ReadStr.OpenKey(key, true) then 
begin 

    Result := ReadStr.GetDataAsString(AttrName); 
end; 

ReadStr.CloseKey; 
ReadStr.Free; 
end; 

,這裏是我的註冊表鍵導出:

Windows Registry Editor Version 5.00 

[HKEY_LOCAL_MACHINE\SOFTWARE\ZES\ACINFO] 
"iamthere"=dword:00000001 
"ArrayOrder"=hex:4d,79,45,78,63,6c,75,64,65 

的問題是,該函數返回空字符串

我甚至嘗試以管理員身份運行到確保它不是權限。

任何幫助?

+2

請勿使用'KEY_WRITE'。刪除。使用'OpenKeyReadOnly'。停止使用'GetDataAsString'。先用'GetData'然後用'TEncoding'解碼ANSI字節數組 –

+0

爲了記錄,你還應該養成調試的習慣。 –

回答

4

對我的評論擴大的問題,我「d使用的代碼如下所示:

function ReadBinString(RootKey: HKEY; Access: LongWord; const KeyName, 
    ValueName: string; Encoding: TEncoding): string; 
var 
    Registry: TRegistry; 
    Bytes: TBytes; 
begin 
    Registry := TRegistry.Create(Access); 
    try 
    Registry.RootKey := RootKey; 
    if Registry.OpenKeyReadOnly(KeyName) then begin 
     SetLength(Bytes, Registry.GetDataSize(ValueName)); 
     Registry.ReadBinaryData(ValueName, Pointer(Bytes)^, Length(Bytes)); 
     Result := Encoding.GetString(Bytes); 
    end else begin 
     Result := ''; 
    end; 
    finally 
    Registry.Free; 
    end; 
end; 

爲你的數據,你會調用它像這樣:

Value := ReadBinString(HKEY_LOCAL_MACHINE, KEY_WOW64_64KEY, 'Software\ZES\ACINFO', 
    'ArrayOrder', TEncoding.ANSI); 

注:

  • 我避免硬編碼的根密鑰。
  • 我用TEncoding來解碼字節數組爲文本。這比GetDataAsString更有效。
  • 我已經允許調用者指定要使用的編碼。
  • 我已經允許調用者指定訪問標誌。
  • 我已使用OpenKeyReadOnly,因爲我們不需要寫入權限。
0

感謝大衛赫弗南我想出了這個解決方案:

function ReadBinString(key: string; AttrName: string): string; 
var 
ReadStr: TRegistry; 
hexStr : string; 
I : Integer; 
begin 
// Result := ''; 
ReadStr := TRegistry.Create(KEY_READ OR KEY_WOW64_64KEY); 
ReadStr.RootKey := HKEY_LOCAL_MACHINE; 

if ReadStr.OpenKey(key, true) then 
begin 

hexStr := ReadStr.GetDataAsString(AttrName); 

hexStr := hexStr.Replace(',',''); 
for I := 1 to length (hexStr) div 2 do 
Result:= Result+Char(StrToInt('$'+Copy(hexStr,(I-1)*2+1,2))); 

end; 

ReadStr.CloseKey; 
ReadStr.Free; 
end; 

感謝David赫弗南再次...這個工作對我來說:

function ReadBinString(key: string; AttrName: string): string; 
    var 
     ReadStr: TRegistry; 
     hexStr: string; 
     I: Integer; 
     Bytes: TBytes; 
     Encoding: TEncoding; 
    begin 

     Encoding := TEncoding.ANSI; 

     Result := ''; 
     ReadStr := TRegistry.Create(KEY_READ OR KEY_WOW64_64KEY); 
     ReadStr.RootKey := HKEY_LOCAL_MACHINE; 
     try 

     if ReadStr.OpenKeyReadOnly(key) then 
     begin 

      SetLength(Bytes, ReadStr.GetDataSize(AttrName)); 
      ReadStr.ReadBinaryData(AttrName, Pointer(Bytes)^, Length(Bytes)); 
      Result := Encoding.GetString(Bytes); 

      // hexStr := ReadStr.GetDataAsString(AttrName); 
      // 
      // hexStr := hexStr.Replace(',',''); 
      // for I := 1 to length (hexStr) div 2 do 
      // Result:= Result+Char(StrToInt('$'+Copy(hexStr,(I-1)*2+1,2))); 

     end; 

     except 

     end; 
     ReadStr.CloseKey; 
     ReadStr.Free; 
    end; 
+0

'GetDataAsString()'旨在將原始字節作爲以十六進制編碼的逗號分隔字符串返回。您正在將其解碼回原始字節,然後將這些值原樣轉換爲字符串字符。爲了簡化,你應該使用ReadBinaryData()來直接讀取原始字節,然後使用'TEncoding.GetString()'將它們轉換爲字符串。像David Heffernan向你展示的那樣。 –

+0

現在,'KEY_READ'沒有必要,可能會泄漏,即'Free'可能不會被調用,'CloseKey'調用是沒有必要的。我不確定這會超出我的答案。 –

相關問題