首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >读取REG_BINARY to String

读取REG_BINARY to String
EN

Stack Overflow用户
提问于 2012-08-13 17:34:21
回答 2查看 2.2K关注 0票数 2

我使用此代码将二进制数据从注册表读取到字符串

代码语言:javascript
复制
function ReadBinary (RootKey: HKEY; SubKey,ValueName: WideString; var Data : String): Bool;
var
  Key     : HKey;
  Buffer  : array of char;
  Size    : Cardinal;
  RegType : DWORD;
begin
  result  := FALSE;
  RegType := REG_BINARY;
  if RegOpenKeyExW(RootKey, pwidechar(SubKey), 0, KEY_READ, Key) = ERROR_SUCCESS then begin
    if RegQueryValueExW(Key,pwidechar(ValueName),NIL,@RegType, NIL,@Size) = ERROR_SUCCESS then begin
      SetLength (Buffer, Size + 1);
      FillChar(Buffer, SizeOf (Buffer), #0);
      if RegQueryValueExW(Key,pwidechar(ValueName),NIL,@RegType, @Buffer[0],@Size) = ERROR_SUCCESS then begin
        result := TRUE;
        Data := String (Buffer); // Shows empty or sometimes 1 random char.
      end;
    end;        
  end;
  RegCloseKey (Key);
end;

EDIT2:

它可以很好地处理固定声明的字节/字符数组

代码语言:javascript
复制
function ReadBinary (RootKey: HKEY; SubKey,ValueName: WideString; var Data : String): Bool;
var
  Key     : HKey;
  Buffer  : array [0..200] of char;
  Size    : Cardinal;
  RegType : DWORD;
begin
  result  := FALSE;
  RegType := REG_BINARY;
  if RegOpenKeyExW(RootKey, pwidechar(SubKey), 0, KEY_READ, Key) = ERROR_SUCCESS then begin
    if RegQueryValueExW(Key,pwidechar(ValueName),NIL,@RegType, NIL,@Size) = ERROR_SUCCESS then begin
      FillChar(Buffer, SizeOf (Buffer), #0);
      if RegQueryValueExW(Key,pwidechar(ValueName),NIL,@RegType, @Buffer,@Size) = ERROR_SUCCESS then begin
        result := TRUE;
        Data   := String (Buffer);
      end;
    end;        
  end;
  RegCloseKey (Key);
end;

我被卡住了。我做错了什么?解决方案是什么?

谢谢你的帮助。

编辑:

我知道我正在从注册表中读取二进制数据。因此,它可能已经是0终止的,并且可能返回错误结果。我可以保证在二进制数据中没有#0字符,因为我之前在值中写了一个很长的文本(带有CR/LF的字符串)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-13 19:31:35

代码语言:javascript
复制
Buffer: array of char;

是动态的字符数组,也就是实际上的指针变量。此字符串将指针重置为Nil:

代码语言:javascript
复制
   FillChar(Buffer, SizeOf (Buffer), #0);

所以现在动态数组无效。

要用零填充动态数组的内容,必须使用

代码语言:javascript
复制
    FillChar(Buffer[0], SizeOf(Buffer[0]) * Length(Buffer), #0)

但这并不是必需的,因为SetLength可以完成这项工作。

票数 6
EN

Stack Overflow用户

发布于 2012-08-13 19:50:30

  1. 动态数组有点像指针。在C/C++中,这是完全相同的。在Delphi中并非如此,但从语义上讲,您可能会这样想。@Buffer不是第一辆车的地址,而是指针本身的地址。Ib对FillChar和RegQueryValueExW的调用都应该传递Buffer和@Buffer,而不是
  2. 为什么要使用Windows API而不是标准的TRegistry?或者TNT Unicode控件或类似的控件有现成的支持unicode的注册表访问。
  3. Win API xxxxxxxW函数支持unicode。你查过你得到的数据了吗?它是8位还是16位?将收到的数据视为十六进制的字节数组-它们是否包含$00字节?看起来他们是这样做的,你把unicode数据放到了缓冲区中。那么,字符串的预期和正确行为将是只接受1个字母(或0,取决于英特尔或摩托罗拉字节顺序)。检查你在Buffer.
  4. Personally,中得到了什么二进制数据,我把缓冲区作为字节数组。然后,在注册表访问之后,如果D7有值,我会使用SetString过程来获取值。如果没有,我会像SetLength(Data,Size);Move(Buffer,Data1,Size)一样复制它;然后我会完全删除FillChar。这种方式复制会稍微快一些,并且不会在第一个零字节时中断。
  5. 在进行低级二进制数据类型转换时,我不会使用模棱两可的字符和字符串类型,而是使用具体的AnsiString和AnsiChar类型。如果你的代码是用新的支持Unicode的Delphi或FreePascal编译的,那就能让它正常工作。快捷方式"char“和"string”可能会根据编译器版本的不同而改变其含义。然后你很难确定它为什么坏了,哪里坏了,该怎么办。--
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11931573

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档