如何从 32 位进程读取 64 位注册表项? [英] How can I read 64-bit registry key from a 32-bit process?

查看:33
本文介绍了如何从 32 位进程读取 64 位注册表项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用 HKEY_LOCAL_MACHINESoftwareMicrosoftCryptography 中的键 MachineGuid 的值来唯一标识主机,但来自运行在 64- 上的 32 位进程位计算机,该值似乎丢失.我猜它是在 Wow6432Node 下搜索的,它确实丢失了.根据这个 应该能够通过添加标志来获得正确的键,但下面的代码似乎仍然无法完成这项工作.我错过了什么?

I've been using the value of key MachineGuid from HKEY_LOCAL_MACHINESoftwareMicrosoftCryptography to uniquely identify hosts, but from 32-bit processes running on 64-bit computers, the value appears to be missing. I guess it's searching under Wow6432Node, where it is indeed missing. According to this you should be able to get to the right key by adding a flag, but below code still doesn't appear to do the job. What am I missing?

const
  KEY_WOW64_64KEY=$0100;
var
  r:HKEY;
  s:string;
  i,l:integer;
begin
  //use cryptography machineguid, keep a local copy of this in initialization?
  l:=40;
  if RegOpenKeyEx(HKEY_LOCAL_MACHINE,PChar('SoftwareMicrosoftCryptography'),
    0,KEY_QUERY_VALUE,r)=ERROR_SUCCESS then
   begin
    SetLength(s,l);
    if RegQueryValue(r,'MachineGuid',PChar(s),l)=ERROR_SUCCESS then
     begin
      SetLength(s,l);
      RegCloseKey(r);
     end
    else
     begin
      //try from-32-to-64
      RegCloseKey(r);
      if RegOpenKeyEx(HKEY_LOCAL_MACHINE,PChar('SoftwareMicrosoftCryptography'),
        0,KEY_QUERY_VALUE or KEY_WOW64_64KEY,r)=ERROR_SUCCESS then
       begin
        l:=40;
        if RegQueryValue(r,'MachineGuid',PChar(s),l)=ERROR_SUCCESS then
          SetLength(s,l)
        else
          l:=0;
        RegCloseKey(r);
       end;
     end;
   end;

推荐答案

你的代码不必要地复杂,主要是因为你没有利用内置的 TRegistry 类来保护你免受所有低级注册表 API 的复杂性.例如,考虑以下代码:

Your code is needlessly complex, largely because you are not taking advantage of the built-in TRegistry class which shields you from all the complexities of the low-level registry API. For example, consider the following code:

type
  TRegistryView = (rvDefault, rvRegistry64, rvRegistry32);

function RegistryViewAccessFlag(View: TRegistryView): LongWord;
begin
  case View of
  rvDefault:
    Result := 0;
  rvRegistry64:
    Result := KEY_WOW64_64KEY;
  rvRegistry32:
    Result := KEY_WOW64_32KEY;
  end;
end;

function ReadRegStr(const Root: HKEY; const Key, Name: string;
  const View: TRegistryView=rvDefault): string;
var
  Registry: TRegistry;
begin
  Registry := TRegistry.Create(KEY_READ or RegistryViewAccessFlag(View));
  try
    Registry.RootKey := Root;
    if not Registry.OpenKey(Key) then
      raise ERegistryException.CreateFmt('Key not found: %s', [Key]);
    if not Registry.ValueExists(Name) then
      raise ERegistryException.CreateFmt('Name not found: %s\%s', [Key, Name]);
    Result := Registry.ReadString(Name);//will raise exception in case of failure
  finally
    Registry.Free;
  end;
end;

ReadRegStr 函数会从相对于根键 Root 的键 Key 返回名为 Name 的字符串值>.如果出现错误,例如键或名称不存在,或者值的类型错误,则会引发异常.

The function ReadRegStr will return the string value named Name from the key Key relative to the root key Root. If there is an error, for example if the key or name do not exists, or if the value is of the wrong type, then an exception will be raised.

View 参数是一个枚举,可让您轻松访问注册表的本机、32 位或 64 位视图.请注意,本机意味着正在运行的进程本机.所以它将是 32 位进程的 32 位视图和 64 位进程的 64 位视图.此枚举反映了 .net 中的等效定义.

The View parameter is an enumeration that makes it simple for you to access native, 32-bit or 64-bit views of the registry. Note that native means native to the process that is running. So it will be the 32-bit view for a 32-bit process and the 64-bit view for a 64-bit process. This enumeration mirrors the equivalent definition in .net.

这篇关于如何从 32 位进程读取 64 位注册表项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆