Sti*_*ers 8 windows delphi registry 64-bit 32bit-64bit
我一直在使用键的值MachineGuid从HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography唯一标识主机,但在64位计算机上运行32位的进程,价值似乎已丢失.我猜它正在Wow6432Node下搜索,它确实缺失了.根据这个你应该能够通过添加一个标志来获得正确的密钥,但是下面的代码似乎仍然不能完成这项工作.我错过了什么?
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;
Run Code Online (Sandbox Code Playgroud)
Rem*_*eau 10
我建议您使用该IsWow64Process()函数来了解何时是在64位操作系统上运行的32进程,然后仅KEY_WOW64_64KEY在该特定条件下应用标志.如果应用程序是32位操作系统上的32位进程,或64位操作系统上的64位进程,则不需要标记.
例如:
const
KEY_WOW64_64KEY = $0100;
var
key: HKEY;
str: string;
len: DWORD;
flag: REGSAM;
wow64: BOOL;
begin
flag := 0;
wow64 := 0;
IsWow64Process(GetCurrentProcess(), @wow64);
if wow64 <> 0 then flag := KEY_WOW64_64KEY;
if RegOpenKeyEx(HKEY_LOCAL_MACHINE, 'Software\Microsoft\Cryptography', 0, KEY_QUERY_VALUE or flag, key) = ERROR_SUCCESS then
try
SetLength(str, 40);
len := Length(str) * SizeOf(Char);
if RegQueryValueEx(key, 'MachineGuid', nil, nil, PByte(Pointer(s)), @len) <> ERROR_SUCCESS then len := 0;
SetLength(str, len div SizeOf(Char));
finally
RegCloseKey(key);
end;
end;
Run Code Online (Sandbox Code Playgroud)
您的代码是不必要的复杂,主要是因为您没有利用内置TRegistry类来保护您免受低级注册表API的所有复杂性的影响.例如,请考虑以下代码:
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;
Run Code Online (Sandbox Code Playgroud)
该函数ReadRegStr将返回相对于根键Name的键所指定的字符串值.如果存在错误,例如,如果键或名称不存在,或者值的类型错误,则会引发异常.KeyRoot
该View参数是一个枚举,使您可以轻松访问注册表的本机,32位或64位视图.请注意,native表示正在运行的进程的本机.因此,对于32位进程,它将是32位视图,对于64位进程,它将是64位视图.此枚举反映了.net中的等效定义.
| 归档时间: |
|
| 查看次数: |
11867 次 |
| 最近记录: |