是否可以从使用inno setup创建的安装程序的[code]部分中的函数退出安装?
我对设置退出代码不感兴趣,我想要做的是对需求执行自定义检查,如果先前未安装该需求,则退出安装.
lep*_*epe 10
如果你在这些事件中,你可以使用Abort():
InitializeSetup
InitializeWizard
CurStepChanged(ssInstall)
InitializeUninstall
CurUninstallStepChanged(usAppMutexCheck)
CurUninstallStepChanged(usUninstall)
Run Code Online (Sandbox Code Playgroud)
我这样做的方式是:
procedure ExitProcess(exitCode:integer);
external 'ExitProcess@kernel32.dll stdcall';
Run Code Online (Sandbox Code Playgroud)
而使用它的方式是:
[Code]
if .... then begin
ExitProcess(0);
end;
Run Code Online (Sandbox Code Playgroud)
为了防止安装程序运行,当先决条件测试失败时,只需False从中返回InitializeSetup.这将在向导显示之前退出安装程序.
function InitializeSetup(): Boolean;
begin
Result := True;
if not PrerequisitesTest then
begin
SuppressibleMsgBox('Prerequisites test failed', mbError, MB_OK, MB_OK);
Result := False;
end;
end;
Run Code Online (Sandbox Code Playgroud)
如果您只需要在安装开始之前测试先决条件(即为时InitializeSetup太早),您可以从以下位置调用该Abort函数CurStepChanged(ssInstall):
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then
begin
if not PrerequisitesTest then
begin
SuppressibleMsgBox('Prerequisites test failed', mbError, MB_OK, MB_OK);
Abort;
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
虽然对于这种情况,请考虑使用PrepareToInstall事件功能机制,而不是退出设置.
function PrepareToInstall(var NeedsRestart: Boolean): String;
begin
Result := '';
if not PrerequisitesTest then
begin
Result := 'Prerequisites test failed';
end;
end;
Run Code Online (Sandbox Code Playgroud)
如果您需要在任何时候强制终止安装程序,请使用ExitProcessWinAPI调用:
procedure ExitProcess(uExitCode: Integer);
external 'ExitProcess@kernel32.dll stdcall';
function NextButtonClick(CurPageID: Integer): Boolean;
begin
if CurPageID = wpReady then
begin
if not PrerequisitesTest then
begin
SuppressibleMsgBox('Prerequisites test failed', mbError, MB_OK, MB_OK);
ExitProcess(1);
end;
end;
Result := True;
end;
Run Code Online (Sandbox Code Playgroud)
虽然这是相当不安全的退出,所以只能将它作为最后的手段.
这是我今天从 Inno 5.6.1 中修改的内容以及您可以在https://github.com/jrsoftware/issrc [ref1]找到的源代码的文章
[Code]
var _ImmediateInnoExit_was_invoked_flag: Boolean; // Inno/Pascal Script initializes all Boolean to False.
procedure ImmediateInnoExit();
var MainFormRef: TForm;
begin
_ImmediateInnoExit_was_invoked_flag := True;
try
MainFormRef := MainForm(); // calls GetMainForm() in Inno pascal code, which will raise an internal exception if the form is not yet initialized.
Log('INFO: ImmediateInnoExit: Calling MainForm.Close()!');
Log('NOTE: If the Event Fn CancelButtonClick is not coded to auto-Confirm, this will display the cancel dialog in the GUI case!');
Log('NOTE: Code will stall inside the Close() function while the Cancel confirmation dialog is displayed.');
MainFormRef.Close(); // this is only effective if the Wizard is visible, but we cann call it even when running siently (as long as the Wizard is initialized)
Log('NOTE: MainForm.Close() invoked. (If confirmed, setup will exit.)');
except
Log('INFO: ImmediateInnoExit did not resolve MainForm -> assuming we were call in an InitializeSetup() context before the Main form has been created!');
end;
Log('INFO: ImmediateInnoExit: Calling Abort() -> EAbort!');
Log('NOTE: Will exit the current scope.');
Log('NOTE: In GUI mode, it will just jump up to the Delphi event loop (and be ignored there). (But the WizardForm.Close() call should lead to exit!)');
Log('NOTE: In Silent Mode, it will be caught and exit the setup.');
Abort(); // Raise EAbort
end;
// This is called when the user clicks the cancel button or the [x] Close button
// the close/cancel can be invoked from code via WizardForm.Close!
procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
Log(Format('IN: CancelButtonClick(%d <- Cancel=[%d], Confirm=[%d])', [CurPageID, Cancel, Confirm]));
Confirm := not _ImmediateInnoExit_was_invoked_flag; // if Confirm==False we don't get the dialog prompt.
Log(Format('IN: CancelButtonClick(%d -> [%d], [%d])', [CurPageID, Cancel, Confirm]));
end;
Run Code Online (Sandbox Code Playgroud)
现在看看上面代码的意义是什么:
AbortInno 文档的Abort状态:
描述:退出当前执行路径而不报告错误。
Abort 会引发一个特殊的“静默异常”,其操作方式与任何其他异常类似,但不会向最终用户显示错误消息。
备注:
Abort不会导致安装程序或卸载程序退出,除非它是从以下事件函数之一(或由它们调用的另一个函数)调用的:
InitializeSetup InitializeWizard CurStepChanged(ssInstall) InitializeUninstall CurUninstallStepChanged(usAppMutexCheck) CurUninstallStepChanged(usUninstall)
Abort 函数以这种方式运行的原因是,Inno 在内部引发了一个EAbort异常,并且该异常由 Delphi UI 循环进行了特殊处理。仅在列出的函数中,Inno 开发人员添加了特殊处理(如[ref2]EAbort的情况),--CurStepChanged(ssInstall)
-- 或者不通过 UI 循环调用的函数 os,就像 的情况一样InitializeSetup,它是从 中的主程序调用的Setup.dpr,并且任何直接操作EAbort都会在该块中专门处理except。
在所有其他 Inno 事件函数(例如NextButtonClick等)中EAbort,异常将到达主程序/UI 循环并在那里被忽略。
这很好地引导我们:
/SILENT运行时(或/VERSILENT)时的 Abort() 行为当Inno静默运行时,它不会显示向导表单UI。然后,“向导”/Inno 的进度不是由 UI 循环驱动,而是由 驱动,它在与例如WizardForm.ClickThroughPages相同的顶级块下调用。[参考3]try/exceptInitializeSetup
因此,如果 Inno 被静默调用,将从每个大多数函数Abort() 中退出安装程序[Code]Abort,并且如果安装程序静默运行,则文档中给出的列表将变得毫无意义。
要取消安装,用户可以单击安装向导的[Cancel]按钮或关闭按钮。[X]
在这种情况下,Inno 将调用回调函数CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean)(如果已定义)并终止安装,可能会出现逃生舱口对话框:
当用户单击“取消”按钮或单击窗口的“关闭”按钮时调用。该
Cancel参数指定是否应该进行正常的取消处理;它默认为True. 该Confirm参数指定是否“退出设置?” 应显示消息框;
用户可以通过调用来[Code]调用取消按钮WizardForm.Close()机制,但这仅在安装程序显示向导表单时有效,并且在静默模式下不起作用。
WizardForm.Close[ref4],或单击实际按钮,最终将调用TMainForm.FormCloseQuery(在 Main.pas 中),它将调用CancelButtonClick回调[ref5]并根据Confirm值,直接调用或首先调用将显示消息框的TerminateApp();辅助函数ExitSetupMsgBox()用户。
.iss .pas 和 .dprissrc\Projects\Main.pas: TMainForm.InstallviaSetStep(ssInstall, False);和whereexcept末尾的块被调用。TMainForm.InstallTerminateAppSetup.dpr调用,即在静默情况下。MainForm.InitializeWizardMain.pasWizardForm.ClickThroughPagesnot InstallMode = imNormalWizardForm.Close()内部调用MainForm.Close()(参见TWizardForm.FormClose:)[Code]:全局CancelButtonClick过程,并且每个向导页面也有一个OnCancelButtonClick: TWizardPageCancelEvent可以设置。| 归档时间: |
|
| 查看次数: |
15371 次 |
| 最近记录: |