存在一些CLSID注册表项但无法读取

时间:2014-10-23 08:18:29

标签: windows delphi winapi registry

我有以下程序读取所有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(它显示了所有内容)。

你有同样的问题,或者我的注册表是否有某种损坏?

1 个答案:

答案 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

总而言之,以下是我的结论:

  • 您的注册表没问题。
  • 您的程序从32位视图读取,但您一直在使用regedit查看64位视图。
  • 并非所有CLSID键都使用REG_SZ作为默认值。

如果您决定要从与程序的位数匹配的其他注册表视图中读取,请使用KEY_WOW64_64KEYKEY_WOW64_32KEY标志来指定视图。详见Accessing an Alternate Registry View。在您的情况下,您可以使用KEY_WOW64_64KEY从64位视图中读取。


另外,您的for循环应该从0而不是1开始。