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
指令使用脚本常量)。
如果我的设置中有这个就好了:
- 如果之前没有安装,则应显示目标目录的编辑字段。
- 如果有以前的安装,则应询问用户是否要覆盖现有安装(无目录 提示应该是可见的)或者如果他想安装这个版本 不同的目录作为单独的安装(卸载列表中的两个条目)。如果选择此选项,则编辑字段 应该显示目标目录。
是否可以使用现有的 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
指令使用脚本常量)。