Inno Setup 根据所选组件更改 AppName
Inno Setup Change AppName based on component(s) selected
我需要安装程序根据(未)选择的组件显示不同的 AppName
。我试过这个:
[Setup]
AppName={code:GetAppName}
AppVersion=1.0
AppVerName=Dagon Video Tools
AppId=Dagon Video Tools
DefaultDirName={sd}\Games\Dagon Video Tools
[Code]
function GetAppName(Value: string): string;
var
CurPageID: Integer;
Begin
Result := 'Dagon Video Tools'
if (CurPageID=wpSelectComponents) and IsComponentSelected('Slasher') and not IsComponentSelected('Frankenstein') then
begin
Result := 'Dagon Slasher';
end;
if (CurPageID=wpSelectComponents) and IsComponentSelected('Frankenstein') and not IsComponentSelected('Slasher') then
begin
Result := 'Dagon Frankenstein';
end;
if (CurPageID=wpSelectComponents) and IsComponentSelected('Slasher') and IsComponentSelected('Frankenstein') then
begin
Result := 'Dagon Video Tools';
end;
End;
但是,如您所料,这是行不通的。这个脚本是不完整的还是应该以完全不同的方式完成?
The AppName
directive value is resolved (= your GetAppName
is called) immediately after the InitializeSetup
(如果有)完成。那是在用户能够更改组件之前很久。
所以你不能AppName
依赖于所选组件。
AppName
的某些用途可以用自定义值覆盖,但不是全部。 见下文。
不过,据我所知,您的问题实际上是关于设置类型的,您可以这样做:
- 创建自定义 "type" 页面(如菜单)作为第一个页面。
- 用户选择 "type" 后,使用自定义开关(例如
/APPTYPE=slasher
)重新启动安装程序并退出。
- 一旦安装程序(重新)运行
/APPTYPE
,您从一开始就知道您正在安装什么 component/type,因此您可以设置 AppName
正常。
- 当然,您跳过自定义 "type" 页面。
这其实是一种更容易实现的方式。唯一的缺点是用户选择"type"后设置window是"recreated"。
如果您不想使用上述解决方案,这是原始回复。
首先,您对 GetAppName
的实施是错误的。您正在使用未初始化的变量 CurPageID
。无论如何,如前所述,GetAppName
甚至在创建向导 window 之前就已被调用,因此 "current page" 与此处无关。
正确的实现应该是这样的:
function GetAppName(Value: string): string;
begin
if IsComponentSelected('Slasher') and not IsComponentSelected('Frankenstein') then
begin
Result := 'Dagon Slasher';
end
else
if IsComponentSelected('Frankenstein') and not IsComponentSelected('Slasher') then
begin
Result := 'Dagon Frankenstein';
end
else
begin
Result := 'Dagon Video Tools';
end;
end;
但这仍然不能使它在 AppName
指令中工作。我们稍后会在其他情况下使用它。
另请注意,对于 , you should better use the WizardSetupType(false)
function 而不是 IsComponentSelected
。
完成标签
只需覆盖 CurPageChanged(wpFinished)
中的 Inno Setup 默认文本:
procedure CurPageChanged(CurPageID: Integer);
var
S: string;
begin
if CurPageID = wpFinished then
begin
S := SetupMessage(msgFinishedHeadingLabel);
StringChange(S, '[name]', GetAppName(''));
WizardForm.FinishedHeadingLabel.Caption := S;
WizardForm.AdjustLabelHeight(WizardForm.FinishedHeadingLabel);
{ Ideally we should shift the FinishedLabel up or down here, }
{ if the height of the header changed. }
{ Note that other messages (msgFinishedLabelNoIcons or msgFinishedRestartLabel) }
{ are used in special situations, so this is not a complete solution. }
S := SetupMessage(msgFinishedLabel);
StringChange(S, '[name]', GetAppName(''));
WizardForm.FinishedLabel.Caption := S;
WizardForm.AdjustLabelHeight(WizardForm.FinishedLabel);
end;
end;
Add/Remove 程序
这很简单。为此有 the UninstallDisplayName
directive,只有在实际安装期间我们已经知道所选组件时才会解决。所以我们可以在这里使用你的(固定的)GetAppName
:
[Setup]
UninstallDisplayName={code:GetAppName}
您确定要完全删除 AppName
及其所有组件吗?
你不能改变它。您最好在 AppName
中使用一些通用名称,以便此消息适用于任何组件。
或者让消息完全不提及应用程序名称:
[Messages]
ConfirmUninstall=Are you sure you want to completely remove this game?
或者完全删除消息:
正在从您的计算机中删除 AppName
,请稍候
与 WizardForm.FinishedLabel
相同的解决方案。只需使用 the InitializeUninstallProgressForm
.
中的 UninstallProgressForm.PageDescriptionLabel
AppName
已成功从您的计算机中删除
类似于 "Are you sure you want to completely remove AppName
and all of its components?"
要么使 AppName
通用。或者使用 "silent" 模式禁用消息并在 the CurUninstallStepChanged(usPostUninstall)
中实现您自己的消息。
再次参见 。
有关类似的讨论,另请参阅 Changing AppName and AppDir depending on language in Inno Setup。
我需要安装程序根据(未)选择的组件显示不同的 AppName
。我试过这个:
[Setup]
AppName={code:GetAppName}
AppVersion=1.0
AppVerName=Dagon Video Tools
AppId=Dagon Video Tools
DefaultDirName={sd}\Games\Dagon Video Tools
[Code]
function GetAppName(Value: string): string;
var
CurPageID: Integer;
Begin
Result := 'Dagon Video Tools'
if (CurPageID=wpSelectComponents) and IsComponentSelected('Slasher') and not IsComponentSelected('Frankenstein') then
begin
Result := 'Dagon Slasher';
end;
if (CurPageID=wpSelectComponents) and IsComponentSelected('Frankenstein') and not IsComponentSelected('Slasher') then
begin
Result := 'Dagon Frankenstein';
end;
if (CurPageID=wpSelectComponents) and IsComponentSelected('Slasher') and IsComponentSelected('Frankenstein') then
begin
Result := 'Dagon Video Tools';
end;
End;
但是,如您所料,这是行不通的。这个脚本是不完整的还是应该以完全不同的方式完成?
The AppName
directive value is resolved (= your GetAppName
is called) immediately after the InitializeSetup
(如果有)完成。那是在用户能够更改组件之前很久。
所以你不能AppName
依赖于所选组件。
AppName
的某些用途可以用自定义值覆盖,但不是全部。 见下文。
不过,据我所知,您的问题实际上是关于设置类型的,您可以这样做:
- 创建自定义 "type" 页面(如菜单)作为第一个页面。
- 用户选择 "type" 后,使用自定义开关(例如
/APPTYPE=slasher
)重新启动安装程序并退出。 - 一旦安装程序(重新)运行
/APPTYPE
,您从一开始就知道您正在安装什么 component/type,因此您可以设置AppName
正常。 - 当然,您跳过自定义 "type" 页面。
这其实是一种更容易实现的方式。唯一的缺点是用户选择"type"后设置window是"recreated"。
如果您不想使用上述解决方案,这是原始回复。
首先,您对 GetAppName
的实施是错误的。您正在使用未初始化的变量 CurPageID
。无论如何,如前所述,GetAppName
甚至在创建向导 window 之前就已被调用,因此 "current page" 与此处无关。
正确的实现应该是这样的:
function GetAppName(Value: string): string;
begin
if IsComponentSelected('Slasher') and not IsComponentSelected('Frankenstein') then
begin
Result := 'Dagon Slasher';
end
else
if IsComponentSelected('Frankenstein') and not IsComponentSelected('Slasher') then
begin
Result := 'Dagon Frankenstein';
end
else
begin
Result := 'Dagon Video Tools';
end;
end;
但这仍然不能使它在 AppName
指令中工作。我们稍后会在其他情况下使用它。
另请注意,对于 WizardSetupType(false)
function 而不是 IsComponentSelected
。
完成标签
只需覆盖 CurPageChanged(wpFinished)
中的 Inno Setup 默认文本:
procedure CurPageChanged(CurPageID: Integer);
var
S: string;
begin
if CurPageID = wpFinished then
begin
S := SetupMessage(msgFinishedHeadingLabel);
StringChange(S, '[name]', GetAppName(''));
WizardForm.FinishedHeadingLabel.Caption := S;
WizardForm.AdjustLabelHeight(WizardForm.FinishedHeadingLabel);
{ Ideally we should shift the FinishedLabel up or down here, }
{ if the height of the header changed. }
{ Note that other messages (msgFinishedLabelNoIcons or msgFinishedRestartLabel) }
{ are used in special situations, so this is not a complete solution. }
S := SetupMessage(msgFinishedLabel);
StringChange(S, '[name]', GetAppName(''));
WizardForm.FinishedLabel.Caption := S;
WizardForm.AdjustLabelHeight(WizardForm.FinishedLabel);
end;
end;
Add/Remove 程序
这很简单。为此有 the UninstallDisplayName
directive,只有在实际安装期间我们已经知道所选组件时才会解决。所以我们可以在这里使用你的(固定的)GetAppName
:
[Setup]
UninstallDisplayName={code:GetAppName}
您确定要完全删除 AppName
及其所有组件吗?
你不能改变它。您最好在 AppName
中使用一些通用名称,以便此消息适用于任何组件。
或者让消息完全不提及应用程序名称:
[Messages]
ConfirmUninstall=Are you sure you want to completely remove this game?
或者完全删除消息:
正在从您的计算机中删除 AppName
,请稍候
与 WizardForm.FinishedLabel
相同的解决方案。只需使用 the InitializeUninstallProgressForm
.
UninstallProgressForm.PageDescriptionLabel
AppName
已成功从您的计算机中删除
类似于 "Are you sure you want to completely remove AppName
and all of its components?"
要么使 AppName
通用。或者使用 "silent" 模式禁用消息并在 the CurUninstallStepChanged(usPostUninstall)
中实现您自己的消息。
再次参见
有关类似的讨论,另请参阅 Changing AppName and AppDir depending on language in Inno Setup。