使用其他(管理员)帐户卸载非管理员安装时,不会删除Inno Setup Uninstall条目

时间:2017-11-02 13:16:39

标签: windows registry inno-setup

Inno Setup Version 5.5.9
Windows 7

我们创建了一个安装包,用于在当前用户的appdata\local\programs文件夹({userpf})中安装该程序。

尝试使用管理员帐户从命令行卸载程序时,它会从文件结构中执行删除操作,但“程序和功能”中的条目仍然存在。您必须进入注册表并删除密钥。

我们做了各种测试。

从用户(管理员)卸载32位应用程序时,它可以正常工作,但在尝试卸载时则不行,用户不是管理员。

卸载64位应用程序时,它不适用于管理员或用户。

当您查看注册表时,32位管理员的条目位于HKEY_LOCAL_MACHINE下,32位用户和64位用户和管理员的条目位于HKEY_USERS下。

当条目在HKEY_USERS下时,它似乎在管理员卸载时不会删除它。

谢谢

Hendriette

1 个答案:

答案 0 :(得分:0)

如果使用没有管理员权限的Inno安装程序安装应用程序,则其Uninstall注册表项将存储到运行安装的本地帐户的HKCU配置单元中。

要卸载此类安装,您必须使用相同的本地帐户。

如果您使用任何其他帐户运行卸载程序,它将无法访问原始帐户的HKCU(确实运行了安装程序),并且无法将其删除。

由具有管理员权限的用户运行卸载程序并不重要。 Inno安装程序不记得,运行安装的帐号是什么。因此,即使管理员也无法识别HKCU Uninstall注册表项要查找的注册表配置单元。

如果您需要支持远程管理,则必须使用管理员权限进行安装和卸载。

如果您需要保留您的方法,则必须修改卸载程序以编程方式识别原始帐户并删除Uninstall注册表项:

const
  { Can use #SetupSetting('AppId') [in curly brackets], }
  { if AppId directive is specified in [Setup] section }
  AppId = 'My Program'; 

procedure RemoveNonAdminUninstallKeys;
var
  Subkeys: TArrayOfString;
  Subkey: string;
  UninstallerLocation: string;
  UninstallKey: string;
  InstallLocation: string;
  I: Integer;
begin
  UninstallerLocation := 
    AddBackslash(ExtractFilePath(ExpandFileName(ExpandConstant('{uninstallexe}'))));
  Log(Format('Uninstalling from "%s"', [UninstallerLocation]));

  RegGetSubkeyNames(HKU, '', Subkeys);

  for I := 0 to GetArrayLength(Subkeys) - 1 do
  begin
    Subkey := Subkeys[I];
    Log(Format('Testing account "%s"', [Subkey]));

    UninstallKey :=
      Subkey + '\Software\Microsoft\Windows\CurrentVersion\Uninstall\' + AppId + '_is1';

    { Would be more appropriate to compare "uninstallexe" against a path }
    { in UninstallString, but that would require more complicated parsing. }
    { Using InstallLocation is easier, and safe, }
    { as long as UninstallFilesDir has its default value of "app" }
    if RegQueryStringValue(HKU, UninstallKey, 'InstallLocation', InstallLocation) then
    begin
      InstallLocation := AddBackslash(ExpandFileName(InstallLocation));
      Log(Format('Checking installation location "%s"', [InstallLocation]));
      if CompareText(InstallLocation, UninstallerLocation) = 0 then
      begin
        Log(Format('Installation location matches, deleting Uninstall key "%s"', [
          UninstallKey]));
        if RegDeleteKeyIncludingSubkeys(HKU, UninstallKey) then
        begin
          Log(Format('Uninstall key "%s" deleted', [UninstallKey]));
        end
          else
        begin
          MsgBox(Format('Failed to delete Uninstall key "%s"', [UninstallKey]),
            mbError, MB_OK);
        end;
        Break; { Do not try other acccounts }
      end;
    end;
  end;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  if CurUninstallStep = usPostUninstall then
  begin
    if IsAdminLoggedOn then
    begin
      Log('Administrator uninstallation, ' +
          'will try to detect if uninstalling non-administrator installation');
      RemoveNonAdminUninstallKeys;
    end;
  end;
end;