我怎样才能读取一个32位进程的64位注册表项? [英] How can I read 64-bit registry key from a 32-bit process?

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

问题描述

我一直在使用的关键的MachineGuid HKEY_LOCAL_MACHINE \ SOFTWARE \微软\加密值来唯一地标识主机,但在64位计算机上运行32位程序,该值将出现丢失。我想这是Wow6432Node,它确实缺少下进行搜索。据这个你的的是能够得到正确的密钥通过添加一个标志,但低于code仍未出现做的工作。我在想什么?

 常量
  KEY_WOW64_64KEY = $ 0100;
变种
  R:HKEY;
  S:串;
  I,L:整数;
开始
  //使用加密的MachineGuid,保持这一个本地副本中初始化?
  L:= 40;
  如果RegOpenKeyEx的(HKEY_LOCAL_MACHINE,为PChar('软件\微软\加密),
    0,KEY_QUERY_VALUE,R)= ERROR_SUCCESS则
   开始
    SetLength(S,L);
    如果RegQueryValue(R,'的MachineGuid',PChar类型(多个),升)= ERROR_SUCCESS然后
     开始
      SetLength(S,L);
      RegCloseKey(r)的;
     结束
    其他
     开始
      //试着从-32到64
      RegCloseKey(r)的;
      如果RegOpenKeyEx的(HKEY_LOCAL_MACHINE,为PChar('软件\微软\加密),
        0,KEY_QUERY_VALUE或KEY_WOW64_64KEY,R)= ERROR_SUCCESS则
       开始
        L:= 40;
        如果RegQueryValue(R,'的MachineGuid',PChar类型(多个),升)= ERROR_SUCCESS然后
          SetLength(S,L)
        其他
          升:= 0;
        RegCloseKey(r)的;
       结束;
     结束;
   结束;
 

解决方案

您code是不必要的复杂,主要是因为你没有充分利用内置的 TRegistry 这使您免受低级别的注册表API的所有复杂类。例如,请考虑以下code:

 键入
  TRegistryView =(rvDefault,rvRegistry64,rvRegistry32);

功能RegistryViewAccessFlag(查看:TRegistryView):长字;
开始
  的情况下查看
  rvDefault:
    结果:= 0;
  rvRegistry64:
    结果:= KEY_WOW64_64KEY;
  rvRegistry32:
    结果:= KEY_WOW64_32KEY;
  结束;
结束;

功能ReadRegStr(常量根:HKEY;常数项,命名为:字符串;
  常量查看:TRegistryView = rvDefault):字符串;
变种
  注册地:TRegistry;
开始
  注册地:= TRegistry.Create(KEY_READ或RegistryViewAccessFlag(查看));
  尝试
    Registry.RootKey:=根;
    如果不是Registry.OpenKey(键),然后
      提高ERegistryException.CreateFmt(键没有发现:%s的,[关键]);
    如果不是Registry.ValueExists(名称),然后
      提高ERegistryException.CreateFmt(名称未找到:%S \%S',[键,名称]);
    结果:= Registry.ReadString(名称); //将失败的情况下引发异常
  最后
    Registry.Free;
  结束;
结束;
 

功能 ReadRegStr 将返回命名的字符串值名称从键相对根密钥。如果有错误,例如,如果该键或名称不存在,或如果该值是错误的类型的,那么异常将引发

查看参数是一个枚举,它使您便捷地访问本地,32位或64位的观点注册表。需要注意的是天然意味着本机到运行的进程。因此,这将是32位视图32位处理和64位视图一个64位的过程。此枚举反映在.net中对应的定义。

I've been using the value of key MachineGuid from HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography 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('Software\Microsoft\Cryptography'),
    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('Software\Microsoft\Cryptography'),
        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;

解决方案

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;

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.

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天全站免登陆