我怎样才能读取一个32位进程的64位注册表项? [英] How can I read 64-bit registry key from a 32-bit process?
问题描述
我一直在使用的关键的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屋!