我有以下程序读取所有CLSID注册表项并在列表框中显示其名称;它是用Delphi编写的,但问题不是特定于Delphi;这是关于Windows注册表的问题。
procedure TForm2.Button1Click(Sender: TObject);
var
guid: string;
reg: TRegistry;
sl: TStringList;
i: Integer;
name: string;
begin
memo1.Clear;
reg := TRegistry.Create;
sl := TStringList.Create;
memo1.Lines.BeginUpdate;
try
reg.RootKey := HKEY_CLASSES_ROOT;
if reg.OpenKeyReadOnly('\CLSID\') then
begin
reg.GetKeyNames(sl);
reg.CloseKey;
for i := 1 to sl.Count-1 do
begin
guid := sl.Strings[i];
if reg.OpenKeyReadOnly('\CLSID\'+guid) then
begin
try
name := reg.ReadString('');
except
name := '!!! <ERROR1> !!!';
end;
reg.CloseKey;
end;
memo1.Lines.Add(guid + ' ' + name);
end;
end;
finally
sl.Free;
reg.Free;
memo1.Lines.EndUpdate;
end;
end;
问题是以下注册表项确实存在(它们在GetKeyNames中列出),但无法读取它们(读取默认值)。我得到了#39;&#39;&#34;&#34;的无效数据类型。
失败的钥匙是:
{33297C9D-2A25-1679-1475-A1CE3901C86D} !!! <ERROR1> !!!
{45049248-47E9-7CEE-A822-1E555F74D237} !!! <ERROR1> !!!
{69C5BE90-E717-97A6-CCEF-C44D93111A5A} !!! <ERROR1> !!!
{8663D540-C578-44AE-9D24-4A9D9A4881C3} !!! <ERROR1> !!!
{9A73B3FA-50DF-3410-930D-51C35FC9237E} !!! <ERROR1> !!!
{EACF7497-3D67-8044-DE95-81429597BB8F} !!! <ERROR1> !!!
这些键不出现在regedit.exe
中,即使我在NT-AUTHORITY \ SYSTEM上下文中显示RegEdit(它显示了所有内容)。
你有同样的问题,或者我的注册表是否有某种损坏?
答案 0 :(得分:4)
明显的解释是密钥存在,但你在错误的地方寻找它们。我打赌你在64位机器上有一个32位进程,键由registry redirector重定向。
在
下的regedit中查找32位CLSID部分HKCR\Wow6432Node\CLSID
可以在MSDN上的Registry Keys Affected by WOW64找到更多有用的信息。
然后,当您找到密钥时,默认值似乎没有您期望的数据类型。你期待一个字符串,但有些键显然有不同的类型。您需要为程序添加一些弹性来处理它。
第一个CLSID,在我的机器上确实找不到HKCR\CLSID
,即64位注册表。但是HKCR\Wow6432Node\CLSID\{33297C9D-2A25-1679-1475-A1CE3901C86D}
下存在。默认值的类型为REG_BINARY
。
总而言之,以下是我的结论:
REG_SZ
作为默认值。如果您决定要从与程序的位数匹配的其他注册表视图中读取,请使用KEY_WOW64_64KEY
或KEY_WOW64_32KEY
标志来指定视图。详见Accessing an Alternate Registry View。在您的情况下,您可以使用KEY_WOW64_64KEY
从64位视图中读取。
另外,您的for
循环应该从0
而不是1
开始。