如何在安装过程中中止/终止 Inno Setup?

发布于 2024-11-15 04:11:05 字数 314 浏览 1 评论 0原文

在安装过程中,我运行一个bat 文件。如果 bat 文件返回错误,我需要中止/终止安装。我希望它执行一个 MsgBox 告诉用户发生了什么,然后中止的外观和行为就像用户按下了取消按钮。

是否可以中止/终止设置?

代码示例将非常感激。

[Run]
Filename: {tmp}\test.bat; WorkingDir: {tmp}; Flags: waituntilterminated runhidden

During my install, I run a bat file. If the bat file returns an error, I need to abort/terminate the setup. I'd like for it to do a MsgBox telling the user what happened, then for the abort to look and act like the user pressed the Cancel button.

Is it possible to abort/terminate the setup?

Code examples would be really appreciated.

[Run]
Filename: {tmp}\test.bat; WorkingDir: {tmp}; Flags: waituntilterminated runhidden

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

笔芯 2024-11-22 04:11:05

谢谢你,罗伯特。当脚本检测到安装无法继续时,这是一个常见问题。
但是,您的解决方案存在问题。 WizardForm.Close 调用取消对话框,并且仅当用户回答“是”时才会停止安装。要明确退出,我们应该调用CancelButtonClick

[Files]
Source: "MYPROG.EXE"; DestDir: "{app}"; AfterInstall: MyAfterInstall

[Code]
var CancelWithoutPrompt: boolean;

function InitializeSetup(): Boolean;
begin
  CancelWithoutPrompt := false;
  result := true;
end;

procedure MyAfterInstall();
begin
  { Do something }
  if BadResult then begin
    MsgBox('Should cancel because...',mbError,MB_OK)
    CancelWithoutPrompt := true;
    WizardForm.Close;
  end;
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
  if CurPageID=wpInstalling then
    Confirm := not CancelWithoutPrompt;
end;

Thank you, Robert. It is a common problem happening any time when script detects that setup cannot be continued.
However, there is a problem in your solution. WizardForm.Close invokes cancel dialog, and installation is stopped only if user answers "Yes". To exit definitely, we should invoke CancelButtonClick.

[Files]
Source: "MYPROG.EXE"; DestDir: "{app}"; AfterInstall: MyAfterInstall

[Code]
var CancelWithoutPrompt: boolean;

function InitializeSetup(): Boolean;
begin
  CancelWithoutPrompt := false;
  result := true;
end;

procedure MyAfterInstall();
begin
  { Do something }
  if BadResult then begin
    MsgBox('Should cancel because...',mbError,MB_OK)
    CancelWithoutPrompt := true;
    WizardForm.Close;
  end;
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
  if CurPageID=wpInstalling then
    Confirm := not CancelWithoutPrompt;
end;
慕巷 2024-11-22 04:11:05

问题是安装过程成功完成后发生[Run]
所以此时无法取消,只能卸载。
此外,[Run] 不允许您获取退出代码。

所以你有几个选择。

使用事件:procedure CurStepChanged(CurStep: TSetupStep);

并使用ExecExecAsOriginalUser调用{tmp}\test.bat 这两个都返回 ResultCode。然后您可以提示用户卸载。

不过我认为执行取消会更容易。

为此,请在项目中的最后一个文件上创建一个 AfterInstall 事件。
并从此事件执行程序,因为您可以从此事件取消。

这是一些示例代码,展示了如何完成它。

[Files]
Source: "MYPROG.EXE"; DestDir: "{app}"; AfterInstall: MyAfterInstall

[Code]
procedure MyAfterInstall();
var
 ResCode : Integer;
begin
 if Exec(ExpandConstant('{tmp}') + '\test.bat',
         '', SW_HIDE, ewWaitUntilTerminated, ResCode) then
 begin
   { Program Ran successfully ResCode now contains exit code results }

   { if Exit was 10 then Cancel Installation. }
   if ResCode = 10 then
   begin
      WizardForm.Close;
   end;       
 end
 else
 begin
   { Problem running Program }
   MsgBox('Error', SysErrorMessage(ResCode), mbError, MB_OK);
 end;

end;

The problem is that [Run] occurs after the Installation process successfully complete.
So you can't cancel at this point, you can only uninstall.
Also [Run] does not allow you to get the exit code.

So you have a few options.

Use Event: procedure CurStepChanged(CurStep: TSetupStep);

And the call the {tmp}\test.bat using Exec or ExecAsOriginalUser both of these return the ResultCode. You can then prompt the user to uninstall.

However I think that performing a cancel would be easier.

To do that, create an AfterInstall Event on the last file in your project.
And execute the program from this event, as you can cancel from this event.

Here is some sample code that shows how it could be done.

[Files]
Source: "MYPROG.EXE"; DestDir: "{app}"; AfterInstall: MyAfterInstall

[Code]
procedure MyAfterInstall();
var
 ResCode : Integer;
begin
 if Exec(ExpandConstant('{tmp}') + '\test.bat',
         '', SW_HIDE, ewWaitUntilTerminated, ResCode) then
 begin
   { Program Ran successfully ResCode now contains exit code results }

   { if Exit was 10 then Cancel Installation. }
   if ResCode = 10 then
   begin
      WizardForm.Close;
   end;       
 end
 else
 begin
   { Problem running Program }
   MsgBox('Error', SysErrorMessage(ResCode), mbError, MB_OK);
 end;

end;
长梦不多时 2024-11-22 04:11:05

我使用了此处答案中的一些代码来编写完整的解决方案,以在 [Run] 部分中安全地运行命令,并提供适当的通知和错误时回滚。

I've used some code from answers here to compose complete solution to run commands safely in [Run] section with proper notification and rollback on error.

顾冷 2024-11-22 04:11:05

只是为了完善其他可能性:

如果您可以在从用户收集任何信息之前检查先决条件,那么进行检查的最佳位置是在 InitializeSetup 函数中。这允许您显示 MsgBox,然后使用 Result := False 退出以中止安装。

如果您需要首先从用户那里收集一些信息(例如安装目录),但仍然可以在不安装任何文件的情况下检查情况(除了通过 ExtractTemporaryFile 进行的一些文件之外),那么最好的地方是在 PrepareToInstall 函数中。这允许您显示错误消息(通过返回错误消息),此时用户可以返回并更正某些内容或自行退出安装。

如果您要检查的条件与特定页面上的用户选择(同样,例如目标目录)具体相关,并且您可以快速进行检查并且根本不需要更改用户的系​​统,那么最好在NextButtonClick;您可以显示一个包含错误的 MsgBox,然后返回 False 以防止转到下一页。

如果您必须等到安装完其他所有内容后才退出安装,那么退出安装就有点太晚了,但如果您无论如何都想这样做,那么罗伯特的回答就足够了。

Just to round out the other possibilities:

If you can check the prerequisite condition before gathering any information from the user, then the best place to do the check is in an InitializeSetup function. This allows you to display a MsgBox and then exit with Result := False to abort the installation.

If you need to gather some information from the user first (such as the installation directory) but can still check the condition without installing any files (other than perhaps a few via ExtractTemporaryFile), then the best place is in the PrepareToInstall function. This allows you to display an error message (by returning it), at which point the user can either go Back and correct something or exit the installation themselves.

If the condition you're checking relates specifically to the user selection on a particular page (again, such as the target directory), and you can do the check quickly and without altering the user's system at all, then it's best to handle that in NextButtonClick; you can display a MsgBox with the error and then return False to prevent moving on to the next page.

If you have to wait until after installing everything else, then it's kinda too late to exit the installation, but if you want to do that anyway then Robert's answer will suffice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文