【发布时间】:2020-06-04 15:55:15
【问题描述】:
如果我的设置中有这个就好了:
- 如果之前没有安装,则应显示目标目录的编辑字段。
- 如果有以前的安装,则应询问用户是否要覆盖现有安装(无目录 提示应该是可见的),或者如果他想在一个 不同的目录作为单独的安装(卸载列表中的两个条目)。如果选择此选项,则编辑字段 应显示目标目录。
是否可以使用现有的 Inno Setup 选项来实现这一点?还是我必须构建一个自定义对话框页面?
【问题讨论】:
如果我的设置中有这个就好了:
是否可以使用现有的 Inno Setup 选项来实现这一点?还是我必须构建一个自定义对话框页面?
【问题讨论】:
在开始时(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 返回一个空字符串。但是,如果您希望用户能够选择要更新的副本,那将更加困难。这对于一个问题来说太多了。
你想做的事情很复杂。如果要保持灵活性,我认为最简单的解决方案是将每个新版本都视为单独的软件。此外,在开始安装时,作为对只希望保留最新版本的用户的礼貌,提供自动卸载以前(最新)的安装。如果用户已经有多个安装,不要做任何具体的事情(或者只是通知用户)。
【讨论】:
我解决了这个问题,让用户(安装应用程序的人)负责通过在安装程序的命令行上指定 /instancename 参数(@ 987654322@ 指令使用脚本常量)。
【讨论】: