Inno Setup 遍历注册表中的用户以删除每个用户 运行 键的条目

Inno Setup iterate through users in Registry to remove entry for each users Run key

我正在寻找一种方法来遍历注册表中的用户,即注册表的 HKEY_USERS 分支),以便删除应用程序可能已在用户配置文件中创建的条目在卸载软件时(即在卸载程序中)在 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run 下。我的理解是每个用户都有一个唯一的 SID,例如HKEY_USERS\S-1-5-21-1832913631-259515069-2567909844-16342 在注册表中。因此 objective 是 return 数组中的用户 SID 列表,然后循环删除 Run.

下的字符串值

我可以使用 RegGetSubkeyNames 到 return HKEY_USERS 下的子项列表:

procedure RemoveAppRunRegEntries();
var
  Subkeys: TArrayOfString;
  I: Integer;
begin
  RegGetSubkeyNames(HKU, '', Subkeys);
  for I := 0 to GetArrayLength(Subkeys) - 1 do
    begin
      RegDeleteValue(HKU, Subkeys[I] + '\Software\Microsoft\Windows\CurrentVersion\Run',
        'App Run String Value');
    end;
end;

但是,有四个默认条目 .DEFAULTS-1-5-18S-1-5-19S-1-5-20,我相信它们在每个 Windows 上都是相同的安装(它们都在我在 Windows 7 和 10 下检查过的安装上),加上附加的相同 SID,在末尾附加了 _Classes,因此对于上面的示例 SID,还有一个 HKEY_USERS\S-1-5-21-1832913631-259515069-2567909844-16342_Classes 子项。因此,在循环之前,我需要找到一种方法从数组中删除这些条目,这样我就只有一个 SID 列表。

这是最好的方法吗?我如何从数组中删除条目以仅保留唯一的用户 SID?还有什么我没有想到的吗?

您不必从数组中删除键,只需在循环中跳过它们即可。

为了 select 正确的键,我正在检查键名中是否有 7 个破折号且没有下划线:

procedure RemoveAppRunRegEntries();
var
  Subkeys: TArrayOfString;
  Subkey: string;
  I, J, Dashes: Integer;
begin
  RegGetSubkeyNames(HKU, '', Subkeys);

  for I := 0 to GetArrayLength(Subkeys) - 1 do
  begin
    Subkey := Subkeys[I];
    Dashes := 0;

    for J := 1 to Length(Subkey) do
    begin
      if Subkey[J] = '-' then
      begin
        Inc(Dashes);
      end;

      if Subkey[J] = '_' then
      begin
        Dashes := -1;
        Break;
      end;
    end;

    if Dashes = 7 then
    begin
      RegDeleteValue(
        HKU, Subkey + '\Software\Microsoft\Windows\CurrentVersion\Run',
        'App Run String Value'); 
    end;
  end;
end;

是的,有一点你没有想到。

Windows 不一定将所有用户加载到 HKEY_USERS——事实上,在许多情况下,只有 DEFAULT 和当前用户(如果是不同的用户,可能还有管理员)会在那里可见。这是因为只有实际登录的用户才会加载他们的注册表配置单元。

如果正在使用漫游配置文件,则可能会出现其他问题,即扰乱其他用户的设置。出于这些原因以及更多原因,一般建议 just leave them alone。 (出于类似的原因,Windows 将默默地忽略指向不再存在的程序的 运行 条目。)

最佳做法是在安装过程中完全不要触及任何用户设置(尤其是不要触及其他用户的设置)。等到任何给定用户 运行 第一次(手动)使用您的应用程序,然后 然后 给他们一个 "welcome experience" 询问他们是否想要 运行 启动时的应用程序和其他此类首选项。所以它分解成这样:

安装程序

  • 写入 HKLM 和通用文件
  • 忽略 HKCU 和用户文件

申请

  • 读写 HKCU 和用户文件
  • 仅当未找到用户版本时才将 HKLM 和常用文件读取为默认值