8

I want to set the exit code for my installation, this way I will know why the installation was aborted. I'm using Inno Setup.

mghie
  • 32,028
  • 6
  • 87
  • 129
Toda Raba
  • 614
  • 1
  • 10
  • 25

3 Answers3

15

From the Inno Setup Help document (from the article "Setup Exit Codes"):

Beginning with Inno Setup 3.0.3, the Setup program may return one of the following exit codes:

0 Setup was successfully run to completion.

1 Setup failed to initialize.

2 The user clicked Cancel in the wizard before the actual installation started, or chose "No" on the opening "This will install..." message box.

3 A fatal error occurred while preparing to move to the next installation phase (for example, from displaying the pre-installation wizard pages to the actual installation process). This should never happen except under the most unusual of circumstances, such as running out of memory or Windows resources.

4 A fatal error occurred during the actual installation process.

Note: Errors that cause an Abort-Retry-Ignore box to be displayed are not fatal errors. If the user chooses Abort at such a message box, exit code 5 will be returned.

5 The user clicked Cancel during the actual installation process, or chose Abort at an Abort-Retry-Ignore box.

6 The Setup process was forcefully terminated by the debugger (Run | Terminate was used in the IDE).

You can easily check if the setup ran successfully by confirming that the exit code is 0. Furthermore:

Any non-zero exit code indicates that Setup was not run to completion.

To answer your question more specifically, you can determine the installation was canceled by observing exit code 2 or 5.

If you wish to return a custom exit code when Inno would otherwise return 0, you can define the following event function:

function GetCustomSetupExitCode: Integer;

From the help document (from the article "Pascal Scripting: Event Functions"):

function GetCustomSetupExitCode: Integer;

Return a non zero number to instruct Setup to return a custom exit code. This function is only called if Setup was successfully run to completion and the exit code would have been 0.

Paul Lammertsma
  • 37,593
  • 16
  • 136
  • 187
  • Tanks a lot. But I mean to set myself the exit code not to use the build-in codes for my specific events. something like exit(88); – Toda Raba Jan 06 '10 at 13:46
  • 3
    I see; I've revised my answer accordingly. Note that you can only define a custom exit code if Inno would have otherwise exited with `0`! – Paul Lammertsma Jan 06 '10 at 15:04
  • is there any way to do the opposite ? specifying to return `0` when inno would otherwise return `!0` ? – v.oddou Feb 05 '14 at 03:42
  • @v.oddou I don't believe that's possible, unless there's some way of intercepting the exit and forcing the process to end using lepe's answer. – Paul Lammertsma Feb 05 '14 at 09:03
  • there might be a way by wrapping the exe into another exe that always returns 0. but in the end for my own case, i just set the parent installer to ignore the return code. (otherwise when cancelling the child installer (made with inno) it would rollback everthing) – v.oddou Feb 06 '14 at 03:56
  • Where I can see these exit codes getting printed.I added a custom exit code and ran the application using command line but the application terminates without printing any such exit code. – Raulp Oct 27 '14 at 09:23
  • 1
    If you're on Windows, [see this answer](http://stackoverflow.com/questions/334879/how-do-i-get-the-application-exit-code-from-a-windows-command-line). On other platforms, the previous exit code is simply returned in `$?`. – Paul Lammertsma Oct 27 '14 at 11:16
8

Use:

[Code]
procedure ExitProcess(exitCode:integer);
  external 'ExitProcess@kernel32.dll stdcall';

procedure SomeEventHere();
begin
  if someerror then begin
    ExitProcess(9); //Your custom exit code
  end;
end;
lepe
  • 24,677
  • 9
  • 99
  • 108
0

Did have this same question and found a way to it:

[Code]
var CustomExitCode: integer;

procedure ExitProcess(exitCode:integer);
    external 'ExitProcess@kernel32.dll stdcall';

procedure DeinitializeSetup();
begin
    if (CustomExitCode <> 0) then
    begin
        DelTree(ExpandConstant('{tmp}'), True, True, True);
        ExitProcess(CustomExitCode);
    end;
end;

And now at any point of your setup just set CustomExitCode to the code you want. Example:

function InitializeSetup: Boolean;
begin
    // Some check did fail, exiting with custom code
    CustomExitCode = -1;
    
    // Let's just close the setup
    Result := false;
end;

This way the setup will not terminate abruptly and you can customize the exit code no matter what state the wizard did exit.

Magus
  • 55
  • 7