Inno Setup遍历Registry中的用户以删除每个用户的条目运行密钥

时间:2016-09-03 13:25:06

标签: registry inno-setup pascalscript

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

我可以使用Run返回RegGetSubkeyNames下的子键列表:

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-19,我相信在每个Windows安装中它们都是相同的(它们都在我在Windows 7和10下检查过的安装,以及附加到最后的S-1-5-20的其他相同SID,因此对于上面的示例SID,还有一个_Classes子项。因此,在循环之前,我需要找到一种从数组中删除这些条目的方法,这样我只有一个SID列表。

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

2 个答案:

答案 0 :(得分:2)

是的,有一些你没有想过的东西。

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

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

最佳做法是在安装过程中根本不触摸任何用户设置(尤其不是其他用户的设置)。等到任何给定的用户第一次运行你的应用程序(手动),然后给他们一个“欢迎体验”,询问他们是否想要在启动时运行应用程序和其他此类首选项。所以它就像这样崩溃了:

安装

  • 撰写HKLM和常用文件
  • 忽略HKCU和用户文件

应用

  • 读取和写入HKCU和用户文件
  • 仅在未找到用户版本的情况下将HKLM和公共文件作为默认值读取

答案 1 :(得分:1)

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

要选择正确的密钥,请检查密钥名称中是否有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;