如何在Delphi 7中使用treeView显示注册表

6
我希望展示一个树形结构,其中包含注册表的所有信息(即所有子键)。我已经编写了以下代码来实现此目的。但是我只得到了一个键的信息,而不是所有键的信息。我的代码缺少什么?
 function TForm1.DisplayKeys(TreeNode : TTreeNode;KeyToSearch:String):String;
 var
  i: Integer;
  RootKey : Integer;
  NewTreeNode : TTreeNode;
  str : TStringList;

 // str2: TStringList;
 begin
   i:=0;

   if reg.OpenKey(KeyToSearch,False) then
   begin
   str:=nil;
   str:=TStringList.create;
   reg.GetKeyNames(str);
   //For all SubKeys
   for i:=0 to str.Count-1 do
   begin
      NewTreeNode:=TreeView1.Items.AddChild(TreeNode, Str.Strings[i]);
      if reg.HasSubKeys then
      begin
        DisplayKeys(NewTreeNode,Str.Strings[i]);
      end;
   end;
 end;

函数的调用如下:

  procedure TForm1.FormCreate(Sender: TObject);
  begin
     reg:=nil;
    reg:=TRegistry.create;
    str2:=nil;
    str2:=TStringList.create;
   reg.RootKey:=HKEY_CURRENT_CONFIG;
   TreeView1.Items.BeginUpdate; //prevents screen repaint every time node is added
      DisplayKeys(nil,''); // call to fn here
   TreeView1.Items.EndUpdate; // Nodes now have valid indexes
 end;

请注意,我没有收到任何错误提示,只是信息不完整。

请注意,如果您在64位系统上运行32位Delphi代码,则会在HKEY_LOCAL_MACHINE\Software下发生注册表重定向。 - Warren P
2个回答

4

一些问题:

  1. 您正在使用 OpenKey 尝试以写访问方式打开键。相反,您应该使用OpenKeyReadOnly。如果您确实想要写入这些键,则必须以管理员身份运行。
  2. 您在完成操作后忘记关闭键。

更严重的是,您使用的相对注册表键不足够。我写了一个小演示控制台应用程序来展示我的意思:

program RegistryEnumerator;

{$APPTYPE CONSOLE}

uses
  Classes, Windows, Registry;

var
  Registry: TRegistry;

procedure DisplayKeys(const Key: string; const Depth: Integer);
var
  i: Integer;
  SubKeys: TStringList;
begin
  if Registry.OpenKeyReadOnly(Key) then begin
    Try
      SubKeys := TStringList.Create;
      Try
        Registry.GetKeyNames(SubKeys);
        for i := 0 to SubKeys.Count-1 do begin
          Writeln(StringOfChar(' ', Depth*2) + SubKeys[i]);
          DisplayKeys(Key + '\' + SubKeys[i], Depth+1);
        end;
      Finally
        SubKeys.Free;
      End;
    Finally
      Registry.CloseKey;
    End;
  end;
end;

begin
  Registry := TRegistry.Create;
  Try
    Registry.RootKey := HKEY_CURRENT_CONFIG;
    DisplayKeys('', 0);
    Readln;
  Finally
    Registry.Free;
  End;
end.

实际上,我打算对注册表进行更改。这将是一个可读写的应用程序。 - CyprUS
你提升了进程吗?你需要管理员权限才能写入这些键。 - David Heffernan
现在我只是读取你看到的键。这不应该有效吗? - CyprUS
谢谢David,它起作用了。关闭注册表键是个好办法。 - CyprUS
2
@CyprUS 如果你查看生成的键并与regedit进行比较,你会发现你的列表是不完整的。我认为你需要维护一个完整的绝对路径到注册表键。相对路径是不够的。请参考我的更新代码,它演示了我认为应该如何完成。 - David Heffernan

0

试试这个:

procedure TForm1.Button1Click(Sender: TObject);
begin

  TreeView1.Items.Clear;
  path := Edit1.Text;
 // reg.RootKey := HKEY_LOCAL_MACHINE ;
  TreeView1.Items.BeginUpdate;

  drawtreeview(nil, path);
  TreeView1.Items.EndUpdate;

end;

procedure TForm1.drawtreeview( node: TTreeNode; name: string);
var
  i: Integer;
  NewTreeNode: TTreeNode;
  str, str2 : TStringList;
  reg : TRegistry;
begin
  reg := TRegistry.Create;
  reg.RootKey := HKEY_LOCAL_MACHINE;
  i := 0;
  if reg.OpenKeyReadOnly(name) then
  begin
    str := TStringList.create;
    reg.GetKeyNames(str);

    for i := 0 to str.Count - 1 do
    begin
      NewTreeNode := TreeView1.Items.AddChild(node, str.Strings[i]);
      if reg.HasSubKeys  then
      begin
        drawtreeview(NewTreeNode,  name + '\' + str.Strings[i]);
      end
      else
      ShowMessage('no sub keys');
    end;

  end;
  reg.CloseKey;
  reg.Free;
end;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接