Inno Setup: How to abort/terminate setup during install?

后端 未结 4 549
眼角桃花
眼角桃花 2020-12-01 12:19

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 wha

相关标签:
4条回答
  • 2020-12-01 12:55

    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.

    0 讨论(0)
  • 2020-12-01 13:01

    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;
    
    0 讨论(0)
  • 2020-12-01 13:07

    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.

    0 讨论(0)
  • 2020-12-01 13:10

    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;
    
    0 讨论(0)
提交回复
热议问题