Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

msi return codes in Inno Setup

I would like to call multiple .msi files in silent mode, and halt the entire installation if any fail.

Is it possible to get the return codes of msiexec.exe being called from the [run] section?

Currently I can only see error messages in the windows event viewer.

like image 491
Rob Hunter Avatar asked Feb 24 '09 16:02

Rob Hunter


People also ask

Can Inno Setup create MSI?

Create MSI with Inno Setup. The MSI Wrapper was produced to create MSI packages from executable files built with Inno Setup. It puts the setup.exe inside an MSI file and runs it with the specified command line switches when the MSI package is installed.

How do I set up an Inno Setup?

Go to Menu, Project, then Compile to compile and create the setup file. This will create a complete installer. Run the Setup and your application will be installed correctly. Innosetup offers an awesome alternative to create great looking Installers for free.

How do I add a checkbox in Inno?

You don't have to manually create checkboxes for that. The standard way to let the user choose what to install is to use the [Types] and [Components] sections of your script file. Take a look at the Components. iss script located in your Inno Setup install folder\examples.

What is Suppressmsgboxes?

/SUPPRESSMSGBOXESInstructs Setup to suppress message boxes. Only has an effect when combined with '/SILENT' or '/VERYSILENT'. The default response in situations where there's a choice is: Yes in a 'Keep newer file? ' situation.


2 Answers

There is currently no way to check the successful execution of [Run] entries. The code just logs the process exit code and continues with the next entry (it can be examined in the Inno Setup source file Main.pas, the function is ProcessRunEntry(), starting at line 3404 in the current version 5.2.3).

If you need to make sure that multiple executions of msiexec were all successful you will need to code an intermediate layer. This can be as simple as a small stub that is executed in the [Run] entries and starts msiexec.exe with the correct parameters, waits for the process to finish, then writes the return code to a file.

Another way to check for success of such an installation step would be to add a custom procedure call for each [Run] entry by using the AfterInstall Parameter. In such a function you could for example check whether an OCX control has been successfully installed:

[Run]
Filename: "{tmp}\MyInstallation1.exe"; Parameters: "/foo"; AfterInstall: AfterMyInstallation1

[Code]
var
  MyInstallation1Success: boolean;

procedure AfterMyInstallation1;
var
  V: Variant;
begin
  try
    V := CreateOleObject('MyInstallation.InstalledOcxControl.1');
    MyInstallation1Success := True;
  except
    MyInstallation1Success := False;
  end;
end;

or whether the directories and registry entries for the dependency are all there.

Each [Run] entry is only executed when its optional Check parameter does return true. So depending on your needs you could either start all silent installations one after the other, and after the last has finished execute a script function to check that all dependencies were successfully installed; or you could write a check function for each dependency installation, which would then return false and thus skip all other installations after the first failed one.

Note however that all [Run] entries are executed after the steps for file copying, registry writing etc. are completed, so you are basically already finished with the installation. If you want to really execute all your installation steps only when all dependencies are correctly installed, then you would have to do that earlier in the process, when the installation can still be cancelled.

Edit: Check out the question "How do you make Inno Setup not look frozen while performing a long Exec?" where some information is given and a sample script is linked to about using the Exec() function for installing dependencies. So if you do not use [Run] entries there is a good chance to achieve what you want.

like image 180
mghie Avatar answered Nov 09 '22 23:11

mghie


You can use my answer to similar question to run commands safely in [Run] section with proper notification and rollback on error.

The link above provides complete solution, but idea is folowing:

1) Write error message to temporary file {tmp}\install.error using InnoSetup's BeforeInstall parameter.

2) Use Windows command shell "cmd.exe /s /c" to run desired program. Also use conditional execution of "del" command with "&&" - http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds_shelloverview.mspx?mfr=true. So error message file would be deleted if command succeed (exit code 0). Please be aware of special quotes handling in "cmd.exe /s /c".

3) Check existence of error message file {tmp}\install.error using InnoSetup's AfterInstall parameter and abort install with proper notification or confirmation (and optional presenting of log file) and perform rollback using Exec(ExpandConstant('{uninstallexe}'), ...

4) There are some additional steps should be done like overriding InnoSetup's ShouldSkipPage(PageID: Integer) function to hide final page, etc.

like image 43
Ivan Samygin Avatar answered Nov 09 '22 22:11

Ivan Samygin