How do I install a JRE from an Inno Setup?

I was able to figure out the issue: Evidently I was mistaken in my use of these lines:

Source: "jre-8u11-windows-x64.exe"; DestDir: "{tmp}\JREInstall.exe"; Check: IsWin64 AND InstallJava();
Source: "jre-8u11-windows-i586.exe"; DestDir: "{tmp}\JREInstall.exe"; Check: (NOT IsWin64) AND InstallJava();

and they should have been in place like so:

Source: "jre-8u11-windows-x64.exe"; DestDir: "{tmp}"; DestName: "JREInstall.exe"; Check: IsWin64 AND InstallJava();
Source: "jre-8u11-windows-i586.exe"; DestDir: "{tmp}"; DestName: "JREInstall.exe"; Check: (NOT IsWin64) AND InstallJava();

That seems to have solved the problem.

Also this line I was mistaken in:

Filename: "{tmp}\JREInstall.exe"; Parameters: "/s"; Flags: nowait postinstall runhidden runascurrentuser; Check: InstallJava()

It should have been:

Filename: "{tmp}\JREInstall.exe"; Parameters: "/s"; Flags: nowait runhidden runascurrentuser; Check: InstallJava()

This is the best solution my limited experience with this particular tool is able to come up with. I will look into the PrepareToInstall option when I have a chance but this works for now.


According to the initial question, "How do I install a JRE from an Inno script?", and taking as a starting solution the best proposed one, I propose a solution that I think works more coherently.

I understand that the user wants to install a JRE for their application if the target computer does not have installed a Java runtime environment or its version is lower than the required one. Ok, what I propose is to use the AfterInstall parameter and reorder a bit the distribution files in a different way.

We will first sort the files in the [Files] section in another way, putting first the redist install files.

Source: "redist\jre-8u121-windows-i586.exe"; DestDir: "{tmp}"; DestName: "JREInstaller.exe";\
    Flags: deleteafterinstall; AfterInstall: RunJavaInstaller(); \
    Check: (NOT IsWin64) AND InstallJava();
Source: "redist\jre-8u121-windows-x64.exe"; DestDir: "{tmp}"; DestName: "JREInstaller.exe"; \
    Flags: deleteafterinstall; AfterInstall: RunJavaInstaller(); \
    Check: IsWin64 AND InstallJava();
Source: "Myprog.exe"; DestDir: "{app}"; Flags: ignoreversion

The next step we must do is to modify the section [Run] as follows.

[Run]
Filename: "{app}\{#MyAppExeName}"; \
    Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \
    Flags: nowait postinstall skipifsilent

And last but not least, we implemented in the [Code] section the RunJavaInstaller() procedure as follows:

[Code]

procedure RunJavaInstaller();
var
  StatusText: string;
  ResultCode: Integer;
  Path, Parameters: string;
begin
  Path := '{tmp}\JREInstaller.exe';
  { http://docs.oracle.com/javase/8/docs/technotes/guides/install/config.html#table_config_file_options }
  Parameters := '/s INSTALL_SILENT=Enable REBOOT=Disable SPONSORS=Disable REMOVEOUTOFDATEJRES=1';
  StatusText:= WizardForm.StatusLabel.Caption;
  WizardForm.StatusLabel.Caption:='Installing the java runtime environment. Wait a moment ...';
  WizardForm.ProgressGauge.Style := npbstMarquee;
  try
    if not Exec(ExpandConstant(Path), Parameters, '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
    begin
      { we inform the user we couldn't install the JRE }
      MsgBox('Java runtime environment install failed with error ' + IntToStr(ResultCode) + 
        '. Try installing it manually and try again to install MyProg.', mbError, MB_OK);
    end;
  finally
    WizardForm.StatusLabel.Caption := StatusText;
    WizardForm.ProgressGauge.Style := npbstNormal;
  end;
end;

You may need to replace the Enabled value with 1 and the Disabled value with 0 if the Java runtime installer is not working properly. I have not experienced any problem doing it this way. Anyways, in the code you have a comment with the Oracle link if you want to take a look.

Finally, since unfortunately we can not receive the installation progress status of the JRE in any way, we show a message and a progress bar so that the user does not have the feeling that the installer has hung. To do this, we save the state before, execute Exec with the flag ewWaitUntilTerminated, to wait for that installation to finish before continuing with ours, and we restore the previous state once the function execution has finished.