0

我有一个 Delphi XE2 项目来在 Windows 注册表中创建一些节点和子节点,如下所述:
应用程序向导

我定义了以下代码:

function GetWinDir: string;
var
  WindowsDirectory: array[0..MAX_PATH] of Char;
begin
   GetWindowsDirectory(WindowsDirectory, MAX_PATH - 1);
   SetLength(Result, StrLen(WindowsDirectory));
   Result := IncludeTrailingPathDelimiter(WindowsDirectory);
end;

function GetSysDir: string;
var
  SystemDirectory: array[0..MAX_PATH] of Char;
begin
  GetSystemDirectory(SystemDirectory, MAX_PATH - 1);
  SetLength(Result, StrLen(SystemDirectory));
  Result := IncludeTrailingPathDelimiter(SystemDirectory);
end;

function GetSysNativeDir: string;
var
  WindowsDirectory: array[0..MAX_PATH] of Char;
begin
   GetWindowsDirectory(WindowsDirectory, MAX_PATH - 1);
   SetLength(Result, StrLen(WindowsDirectory));
   Result := IncludeTrailingPathDelimiter(WindowsDirectory)  + 'Sysnative\';
end;

procedure TMainForm.BitBtn01Click(Sender: TObject);
var
  RegistryEntry : TRegistry;
  RegistryEntryValue : string;   
begin
  RegistryEntry := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);
  RegistryEntry.RootKey := HKEY_CLASSES_ROOT;
  if (not RegistryEntry.KeyExists('CLSID\{BE800AEB-A440-4B63-94CD-AA6B43647DF9}\')) then
    begin
      RegistryEntry.Access:= KEY_WRITE or KEY_WOW64_64KEY;
      if RegistryEntry.OpenKey('CLSID\{00000000-0000-0000-0000-000000000001}\',true) then
        begin
          Memo01.Font.Color := 3992580;
          Memo01.Lines.Add('Windows Registry Entry Has Been Found In Your System');
          RegistryEntry.WriteString('', 'Delphi Application Wizard');
          RegistryEntry.OpenKey('Subnode 01\',true);
          RegistryEntry.WriteExpandString('', '%SystemRoot%\System32\Application Wizard 01.dll');
          RegistryEntry.WriteString('Subnode String 01', '00001');
          RegistryEntry.CloseKey();
          RegistryEntry.OpenKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 02\',true);
          RegistryEntry.WriteExpandString('', '%SystemRoot%\System32\Application Wizard 02.dll');
          RegistryEntry.WriteString('Subnode String 02', '00002');
          RegistryEntry.CloseKey();
          RegistryEntry.OpenKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 03\',true);
          RegistryEntry.WriteExpandString('', '%SystemRoot%\System32\Application Wizard 03.dll');
          RegistryEntry.WriteString('Subnode String 03', '00003');
          RegistryEntry.CloseKey();
          RegistryEntry.OpenKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 04\',true);
          RegistryEntry.WriteExpandString('', '%SystemRoot%\System32\Application Wizard 04.dll');
          RegistryEntry.WriteString('Subnode String 04', '00004');
          RegistryEntry.CloseKey();
          RegistryEntry.OpenKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 05\',true);
          RegistryEntry.WriteExpandString('', '%SystemRoot%\System32\Application Wizard 05.dll');
          RegistryEntry.WriteString('Subnode String 05', '00005');
          Memo01.Font.Color := 3992580;
          Memo01.Lines.Add('Windows Registry Entry Has Been Created Successfully')
        end
      else if RegistryEntry.OpenKey('CLSID\{00000000-0000-0000-0000-000000000001}\',false) then
        begin
          Memo01.Font.Color := 7864575;
          Memo01.Lines.Add('Windows Registry Entry Has Not Been Created Successfully')
        end
    end
  else
    begin
      if (RegistryEntry.KeyExists('CLSID\{00000000-0000-0000-0000-000000000001}\')) then
        begin
          Memo01.Font.Color := 7864575;
          Memo01.Lines.Add('Windows Registry Entry Has Been Found In Your System')
        end;
    end;
  RegistryEntry.CloseKey();
  RegistryEntry.Free;
end;

..
..
..
..
..
procedure TMainForm.BitBtn02Click(Sender: TObject);
var
  RegistryEntry : TRegistry;
begin
  RegistryEntry := TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);
  RegistryEntry.RootKey := HKEY_CLASSES_ROOT;
  if (RegistryEntry.KeyExists('CLSID\{00000000-0000-0000-0000-000000000001}\')) then
    begin
      Memo01.Font.Color := 3992580;
      Memo01.Lines.Add('Windows Registry Entry Has Been Found In Your System');
      RegistryEntry.Access:= KEY_WRITE or KEY_WOW64_64KEY;
      RegistryEntry.DeleteKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 01\');
      RegistryEntry.DeleteKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 02\');
      RegistryEntry.DeleteKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 03\');
      RegistryEntry.DeleteKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 04\');
      RegistryEntry.DeleteKey('CLSID\{00000000-0000-0000-0000-000000000001}\Subnode 05\');
      RegistryEntry.DeleteKey('CLSID\{00000000-0000-0000-0000-000000000001}\');
      RegistryEntry.CloseKey();
      RegistryEntry.Free;
      Memo01.Font.Color := 16756480;
      Memo01.Lines.Add('Windows Registry Entry Has Been Deleted Successfully');
    end
  else
    begin
      Memo01.Font.Color := 7864575;
      Memo01.Lines.Add('Windows Registry Entry Has Not Been Found In Your System');
    end;
end;  

我的问题是:

  1. 尽管我正在尝试为%SystemRoot%\System32\Application Wizard 01.dll尚未%SystemRoot%\SysWow64\Application Wizard 01.dll写入的每个子节点编写默认字符串。如何避免这种情况?

  2. 在子节点 01 中写入一些字符串之后,当我试图在子节点 02 中写入一些字符串等等时,是否每次都必须调用主节点CloseKey();OpenKey就像我在代码中所做的那样。或者有没有其他解决方案?

  3. 如果我想使用一些代码删除主节点,我必须先删除子节点 05,然后删除子节点 04 ...等等。只有在删除所有子节点后,我才能删除主节点。如果任何子节点包含另一个子节点,我会检查这些东西。有什么解决方案可以直接删除主节点而不是删除那些子节点?

4

1 回答 1

2

为什么 system32 会映射到 SysWOW64?

这是注册表的一个相当模糊的角落。因为您的进程是 32 位进程,所以注册表重定向器会插入。该文档指出:

此外,包含 system32 的 REG_SZ 或 REG_EXPAND_SZ 键被替换为 syswow64。该字符串必须以指向或位于 %windir%\system32 下的路径开头。字符串比较不区分大小写。环境变量在匹配路径之前被扩展,因此以下所有路径都被替换:%windir%\system32、%SystemRoot%\system32和C:\windows\system32。

解决此问题的最简单(也可能是唯一)方法是从 64 位进程执行写入,从而摆脱注册表重定向器的控制。


我必须调用OpenKey()我写的每个不同的键吗?

是的。


是否必须先清空所有子项才能删除密钥?

从以下文档TRegistry.DeleteKey

调用 DeleteKey 以从注册表中删除指定的键及其关联数据(如果有)。在 Windows 95 下,如果键具有子键,则子键和任何关联数据也将被删除。在 Windows NT 下,必须通过单独调用 DeleteKey 来显式删除子项。

这样做的原因是DeleteKey调用RegDeleteKeyEx文档状态:

要删除的子项不能有子项。要删除一个键及其所有子键,您需要枚举子键并单独删除它们。要递归删除键,请使用 RegDeleteTree 或 SHDeleteKey 函数。

因此,如果您准备直接调用 Windows API 函数,您可以在一次 API 调用中删除一个键及其子键,使用上述任一函数。

如果您需要支持 XP,请使用SHDeleteKey您这样称呼的 XP:

SHDeleteKey(HKEY_CLASSES_ROOT, PChar(SubKeyName));
于 2013-05-05T15:53:14.607 回答