I'm trying to install the most current platform (x64 or x86) appropriate Java Runtime Environment via Inno Setup (along with another application). I've found some script examples for how to detect the version and install if correct and adapted them to my needs but I keep running into this:
Unable to open file "path\to\JREInstall.exe":
CreateProcess failed: Code 5:
Access Is Denied
This is the code strictly responsible for installing the JRE:
[Setup]
AppName="JRE Setup"
AppVersion=0.1
DefaultDirName="JRE Setup"
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
[Files]
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();
[Run]
Filename: "{tmp}\JREInstall.exe"; Parameters: "/s"; \
Flags: nowait postinstall runhidden runascurrentuser; Check: InstallJava()
[Code]
procedure DecodeVersion(verstr: String; var verint: array of Integer);
var
i,p: Integer; s: string;
begin
{ initialize array }
verint := [0,0,0,0];
i := 0;
while ((Length(verstr) > 0) and (i < 4)) do
begin
p := pos ('.', verstr);
if p > 0 then
begin
if p = 1 then s:= '0' else s:= Copy (verstr, 1, p - 1);
verint[i] := StrToInt(s);
i := i + 1;
verstr := Copy (verstr, p+1, Length(verstr));
end
else
begin
verint[i] := StrToInt (verstr);
verstr := '';
end;
end;
end;
function CompareVersion (ver1, ver2: String) : Integer;
var
verint1, verint2: array of Integer;
i: integer;
begin
SetArrayLength (verint1, 4);
DecodeVersion (ver1, verint1);
SetArrayLength (verint2, 4);
DecodeVersion (ver2, verint2);
Result := 0; i := 0;
while ((Result = 0) and ( i < 4 )) do
begin
if verint1[i] > verint2[i] then
Result := 1
else
if verint1[i] < verint2[i] then
Result := -1
else
Result := 0;
i := i + 1;
end;
end;
function InstallJava() : Boolean;
var
ErrCode: Integer;
JVer: String;
InstallJ: Boolean;
begin
RegQueryStringValue(
HKLM, 'SOFTWARE\JavaSoft\Java Runtime Environment', 'CurrentVersion', JVer);
InstallJ := true;
if Length( JVer ) > 0 then
begin
if CompareVersion(JVer, '1.8') >= 0 then
begin
InstallJ := false;
end;
end;
Result := InstallJ;
end;
In the full setup script the same message continues to come up.
How can I get the JRE Setup to run from this scripted setup file?
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.