Inno Setup:覆盖现有安装或显示目录提示

Inno Setup: Overwrite existing installation or show dir prompt

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

是否可以使用现有的 Inno Setup 选项来实现此目的?或者我是否必须构建自定义对话框页面?

开头(InitializeSetup event function), check if the application is installed already (see GetUninstallString in the code below). If it is, ask user, what to do (see MsgBox use in the code and the first screenshot). If user chooses to update the existing installation, proceed normally. Inno Setup by default does not allow changing installation path of an existing installation (see DisableDirPage).

如果用户选择安装另一个副本,请将 AppId to a new unique value (GetAppId function in the code). This will make Inno Setup treat the installation as new, so it will prompt for the installation path. Update also UninstallDisplayName, so that the user can distinguish the installations when choosing which copy to uninstall (see GetAppIdentification and the third screenshot). Also update 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 returns 为空字符串。但是如果您希望用户能够选择要更新的副本,那就更难了。一个问题太多了。


你要做的事情很复杂。如果您想保持灵活性,我认为最简单的解决方案是将每个新版本都视为一个单独的软件。此外,在开始安装时,出于对那些只想保留最新版本的人的礼貌,自动卸载以前(最新)的安装。如果用户已经有多个安装,则不执行任何特定操作(或仅通知用户)。

我解决了这个问题,方法是让用户(安装应用程序的人)负责通过在安装程序的命令中指定 /instancename 参数来明确指定他们想要安装应用程序的单独实例行(AppId 指令使用脚本常量)。