【问题标题】:Inno Setup: Overwrite existing installation or show dir promptInno Setup:覆盖现有安装或显示目录提示
【发布时间】:2020-06-04 15:55:15
【问题描述】:

如果我的设置中有这个就好了:

  • 如果之前没有安装,则应显示目标目录的编辑字段。
  • 如果有以前的安装,则应询问用户是否要覆盖现有安装(无目录 提示应该是可见的),或者如果他想在一个 不同的目录作为单独的安装(卸载列表中的两个条目)。如果选择此选项,则编辑字段 应显示目标目录。

是否可以使用现有的 Inno Setup 选项来实现这一点?还是我必须构建一个自定义对话框页面?

【问题讨论】:

    标签: installation inno-setup


    【解决方案1】:

    在开始时(InitializeSetup event function),检查应用程序是否已经安装(参见下面代码中的GetUninstallString)。如果是,请询问用户,该怎么做(参见代码中的MsgBox 使用和第一个屏幕截图)。如果用户选择更新现有安装,请正常进行。默认情况下,Inno Setup 不允许更改现有安装的安装路径(请参阅DisableDirPage)。

    如果用户选择安装另一个副本,请将AppId 设置为新的唯一值(代码中的GetAppId 函数)。这将使 Inno Setup 将安装视为新安装,因此它会提示输入安装路径。还更新UninstallDisplayName,以便用户在选择要卸载的副本时区分安装(参见GetAppIdentification 和第三个屏幕截图)。还将DefaultDirName 更新为新的唯一路径(参见GetAppIdentification 和第三个屏幕截图)。

    #define AppName "My Program"
    #define AppVersion "1.5"
    
    [Setup]
    AppId={code:GetAppId}
    AppName={#AppName}
    AppVersion={#AppVersion}
    UninstallDisplayName={#AppName} {#AppVersion}{code:GetAppIdentification}
    UsePreviousLanguage=no # Needed when AppId is dynamic
    DefaultDirName={autopf}\My Program{code:GetAppIdentification}
    
    [Code]
    
    var
      Instance: string;
    
    function GetAppId(Param: string): string;
    begin
      Result := '{#AppName}' + Instance;
    end;
    
    function GetAppIdentification(Param: string): string;
    begin
      if Instance <> '' then Result := ' (' + Instance + ')';
    end;
    
    function GetUninstallString(): string;
    var
      UninstallKey: string;
    begin
      UninstallKey :=
        'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + GetAppId('') + '_is1';
      RegQueryStringValue(HKA, UninstallKey, 'UninstallString', Result);
      Log(Result)
    end;
    
    function InitializeSetup(): Boolean;
    var
      Message: string;
      Answer: Integer;
    begin
      Result := True;
      if GetUninstallString() = '' then
      begin
        Log('Application is not installed yed, installing the first copy');
      end
        else
      begin
        Log('Application is installed already, asking what to do');
        Message :=
          'This program is installed already, ' +
          'do you want to update the existing installation? ' +
          'Press No to install another copy of the program';
        Answer := MsgBox(Message, mbConfirmation, MB_YESNOCANCEL);
        if Answer = IDYES then
        begin
          Log('User chose to update the installation');
        end
          else
        if Answer = IDNO then
        begin
          Log('User chose to install another copy');
          Instance := '2';
        end
          else
        begin
          Log('User chose to abort the installation');
          Result := False;
        end;
      end;
    end;
    


    现在的问题是,如果已经有两个安装,该怎么办。要制作第三个(或更多),很简单,只需循环,增加Instance 中的值,直到GetUninstallString 返回一个空字符串。但是,如果您希望用户能够选择要更新的副本,那将更加困难。这对于一个问题来说太多了。


    你想做的事情很复杂。如果要保持灵活性,我认为最简单的解决方案是将每个新版本都视为单独的软件。此外,在开始安装时,作为对只希望保留最新版本的用户的礼貌,提供自动卸载以前(最新)的安装。如果用户已经有多个安装,不要做任何具体的事情(或者只是通知用户)。

    【讨论】:

    • 当然。你想做的事情很复杂。如果要保持灵活性,我认为最简单的解决方案是将每个新版本都视为单独的软件。此外,在开始安装时,作为对只希望保留最新版本的用户的礼貌,提供自动卸载以前(最新)的安装。如果用户已经进行了多次安装,则无需执行任何具体操作(或只通知用户)。
    • 好的,我认为这是最好的解决方案。非常感谢!我正在使用此代码stackoverflow.com/questions/2000296/… 我将尝试以它为我提供最新安装版本的方式对其进行修改。我想我必须使用“InstallDate”注册表项。
    【解决方案2】:

    我解决了这个问题,让用户(安装应用程序的人)负责通过在安装程序的命令行上指定 /instancename 参数(@ 987654322@ 指令使用脚本常量)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-04
      • 2011-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多