Inno Setup:在 [运行] 部分执行 Pascal 函数
Inno Setup: Execute a Pascal function in [Run] section
在安装结束时,我需要 运行 更新飞行模拟器 .cfg
文件(在 Inno Setup 中称为 .ini
文件)的 Pascal 函数。 Pascal 函数存在于其 [Code]
部分并且 运行s 是正确的。我想 运行 [Run]
部分中的这个 Pascal 函数使用 StatusMsg
来告诉用户发生了什么。
[Run]
Filename: {code:FsxEditSceneryFile|Add#<scenerySpec>}; StatusMsg: "Add scenery to FSX";
; <scenerySpec> is just a place holder of the actual scenery specification!
除 Inno Setup 强制我使用 string
作为 Pascal 函数的 return 值外,一切都按预期工作。然而,Filename
语句需要一个 Boolean
作为 return 值来指定执行是成功 (True
) 还是失败 (False
)。这种类型不匹配会在 Filename
语句执行结束时产生一个错误消息框,说
CreateProcess failed; Code 87. Wrong Parameter.
任何建议如何解决这个问题?我知道存在我可以使用的事件函数,例如CurStepChanged()
但我发现 StatusMsg
机制非常好,可以告诉用户安装完成了什么。
您正在滥用 Filename
参数解析来执行某些代码。解析参数值时未记录。这使您的方法不可靠。在显示 StatusMsg
时,您无法知道该值已解析。此外,该值无论如何都必须解析为可执行路径。 Inno Setup 将尝试执行它(因此出现错误)。你可能不想要什么。不要那样做。
相反,正如您已经建议的,使用 CurStepChanged
。您可以通过访问 WizardForm.StatusLabel
.
来显示来自 Pascal 代码的状态消息
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
begin
WizardForm.StatusLabel.Caption := 'Installing something...';
{ Install something }
end;
end;
万一其他人遇到这个问题,这里有一个解决方案,可以让您 运行 Pascal 脚本程序“就地”在 [RUN]
部分中的任何语句。
我需要将 powershell 脚本的执行移动到 [CODE]
部分,因为 [RUN]
部分不提供对外部 cmd 程序的退出代码做出反应的方法。
因为我有一堆子安装程序,我需要在我的设置中以特定顺序执行,所以可以选择控制 [RUN]
部分中 pascal 脚本的位置,而不仅仅是何时进入 [运行] 部分设置步骤。
它的工作原理是使用“虚拟”程序(如 ping
)作为 [RUN]
语句的文件名,然后使用内置的 BeforeInstall
参数调用 pascal 脚本包含实际执行逻辑的过程。
[运行]节
Filename: "ping"; BeforeInstall: RunSQLSetupScript; Components: "thirds\db"; StatusMsg: "Installing SQL Server ..." ; Flags: runhidden
包含实际执行逻辑的 Pascal 脚本程序
(请注意,{tmp}\{#SQLServerInstallScript}
将是此示例中脚本的实际路径,因为通常建议避免硬编码路径并改用常量 + 临时目录。)
// runs the SQL setup script and terminates the setup process, if the script returns an exit code that indicates an error
procedure RunSQLSetupScript();
var
runSuccess: Boolean;
retVar: Integer;
msgText: String;
begin
runSuccess := ShellExec('', 'powershell.exe', '-NoProfile -File ' + ExpandConstant('{tmp}\{#SQLServerInstallScript}'), '', SW_SHOW, ewWaitUntilTerminated, retVar);
// the external script will return an exit code > 0 if an error occurred
if (runSuccess = False) or (retVar > 0) then
begin
msgText := 'SQL Server setup script returned error code ' + IntToStr(retVar) + ', indicating an unsuccessful installation of SQL Server. Setup will now terminate.';
MsgBox(msgText, mbCriticalError, MB_OK);
// => further handle error case here, like cancelling the running setup or log the issue etc.
end;
end;
在安装结束时,我需要 运行 更新飞行模拟器 .cfg
文件(在 Inno Setup 中称为 .ini
文件)的 Pascal 函数。 Pascal 函数存在于其 [Code]
部分并且 运行s 是正确的。我想 运行 [Run]
部分中的这个 Pascal 函数使用 StatusMsg
来告诉用户发生了什么。
[Run]
Filename: {code:FsxEditSceneryFile|Add#<scenerySpec>}; StatusMsg: "Add scenery to FSX";
; <scenerySpec> is just a place holder of the actual scenery specification!
除 Inno Setup 强制我使用 string
作为 Pascal 函数的 return 值外,一切都按预期工作。然而,Filename
语句需要一个 Boolean
作为 return 值来指定执行是成功 (True
) 还是失败 (False
)。这种类型不匹配会在 Filename
语句执行结束时产生一个错误消息框,说
CreateProcess failed; Code 87. Wrong Parameter.
任何建议如何解决这个问题?我知道存在我可以使用的事件函数,例如CurStepChanged()
但我发现 StatusMsg
机制非常好,可以告诉用户安装完成了什么。
您正在滥用 Filename
参数解析来执行某些代码。解析参数值时未记录。这使您的方法不可靠。在显示 StatusMsg
时,您无法知道该值已解析。此外,该值无论如何都必须解析为可执行路径。 Inno Setup 将尝试执行它(因此出现错误)。你可能不想要什么。不要那样做。
相反,正如您已经建议的,使用 CurStepChanged
。您可以通过访问 WizardForm.StatusLabel
.
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
begin
WizardForm.StatusLabel.Caption := 'Installing something...';
{ Install something }
end;
end;
万一其他人遇到这个问题,这里有一个解决方案,可以让您 运行 Pascal 脚本程序“就地”在 [RUN]
部分中的任何语句。
我需要将 powershell 脚本的执行移动到 [CODE]
部分,因为 [RUN]
部分不提供对外部 cmd 程序的退出代码做出反应的方法。
因为我有一堆子安装程序,我需要在我的设置中以特定顺序执行,所以可以选择控制 [RUN]
部分中 pascal 脚本的位置,而不仅仅是何时进入 [运行] 部分设置步骤。
它的工作原理是使用“虚拟”程序(如 ping
)作为 [RUN]
语句的文件名,然后使用内置的 BeforeInstall
参数调用 pascal 脚本包含实际执行逻辑的过程。
[运行]节
Filename: "ping"; BeforeInstall: RunSQLSetupScript; Components: "thirds\db"; StatusMsg: "Installing SQL Server ..." ; Flags: runhidden
包含实际执行逻辑的 Pascal 脚本程序
(请注意,{tmp}\{#SQLServerInstallScript}
将是此示例中脚本的实际路径,因为通常建议避免硬编码路径并改用常量 + 临时目录。)
// runs the SQL setup script and terminates the setup process, if the script returns an exit code that indicates an error
procedure RunSQLSetupScript();
var
runSuccess: Boolean;
retVar: Integer;
msgText: String;
begin
runSuccess := ShellExec('', 'powershell.exe', '-NoProfile -File ' + ExpandConstant('{tmp}\{#SQLServerInstallScript}'), '', SW_SHOW, ewWaitUntilTerminated, retVar);
// the external script will return an exit code > 0 if an error occurred
if (runSuccess = False) or (retVar > 0) then
begin
msgText := 'SQL Server setup script returned error code ' + IntToStr(retVar) + ', indicating an unsuccessful installation of SQL Server. Setup will now terminate.';
MsgBox(msgText, mbCriticalError, MB_OK);
// => further handle error case here, like cancelling the running setup or log the issue etc.
end;
end;