32位程序如何读取“真正”的64位注册表版本?

17

我正在使用OpenKeyReadOnlyGetValueNames读取HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run,但它返回了来自HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run的值。

如何阅读64位的值而不是从32位密钥重定向过来的值?

程序已经以管理员账户运行。我也尝试使用RegOpenKeyExRegEnumValue

我正在使用Delphi 2010。

1个回答

27

打开注册表时,必须使用KEY_WOW64_64KEY值和TRegistry类。

来自 MSDN :

KEY_WOW64_64KEY 表示在 64 位 Windows 上的应用程序应当操作 64 位注册表视图。该标记在 32 位 Windows 上被忽略。

该标记必须使用 OR 运算符与此表中其他查询或访问注册表值的标志组合使用。

可以尝试此示例应用程序。

{$APPTYPE CONSOLE}

uses
  Windows,
  Classes,
  registry,
  SysUtils;


procedure ReadRegistry;
var
  Registry: TRegistry;
  List    : TStrings;
begin
  Registry := TRegistry.Create(KEY_WRITE OR KEY_WOW64_64KEY);
  //Registry := TRegistry.Create(KEY_READ OR KEY_WOW64_64KEY);
  List     := TStringList.Create;
  try
    Registry.RootKey := HKEY_LOCAL_MACHINE;
    if Registry.OpenKeyReadOnly('\SOFTWARE\Microsoft\Windows\CurrentVersion\Run') then
    begin
       Registry.GetValueNames(List);
       Writeln(List.Text);
    end;
    Registry.CloseKey;
  finally
    Registry.Free;
    List.Free;
  end;
end;

begin
  try
   ReadRegistry();
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
  Readln;
end.

2
据我所知,这个例子是错误的,因为OpenKeyReadOnly会将Access属性重置为KEY_READ,而没有KEY_WOW64_64KEY。因此,您仍然在读取32位版本。也许以后的Delphi版本会保留KEY_WOW64_64KEY,但我无法检查。 - The_Fox
2
@TheFox,我在 Windows 7 64 位系统下测试了 Delphi 2007 和 Delphi XE 中的代码,并且在两个版本中都正常工作。 - RRUZ
1
这个方法是可行的,但是如果你想要递归枚举注册表,就有一个问题。如果你传入KEY_WOW64_64KEY并且遇到了Wow6432Node键之一(在regedit中是32位注册表),它会再次返回64位基本键,因此你可以无限下降。我们唯一找到的解决方法是通过键名循环向上,并在任何父级命名为“Wow6432Node”时恢复到32位访问。 - Zoë Peterson
1
哎呀!我在发布问题时发现了这个,非常需要帮助。经过一天的调试后,我得出结论,同一个应用程序(Delphi XE5)在64位下可以工作,在32位下则失败。我都快疯了。很高兴在这里看到这个。 - Chris Thornton
1
该死!Delphi2005中没有WOW64相关的内容。是的,我们正在升级。除了修改注册表单元之外,还有其他解决方法吗? - Chris Thornton
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接