I\'m creating an Inno Setup installer for a jar app. What I want to do right now is to check if java is present before proceeding with the install. So I only need to be sure the
There is another way now. You can include a Stub setup - online installer, which will download and install actual setup.
The filename name as for now is JavaSetup8u121.exe
, which suggests it might be version specific. I don't have an older one to test if it will download actual or specific, older version.
And for now, it seems it only does install 32bit JRE.
[Files]
#define JavaInstaller "JavaSetup8u121.exe"
Source: "include\{#JavaInstaller}"; DestDir: "{tmp}";
[Code]
const
REQUIRED_JAVA_VERSION = '1.7';
function isJavaInstalled(): Boolean;
var
JavaVer : String;
tmpFileName,
pathJavaExe: String;
isGoodJavaVersion,
isFoundJavaPath: Boolean;
ResultCode: Integer;
ExecStdout: AnsiString;
begin
{ *** check in registry }
{ sets variables: }
{ JavaVer }
{ isGoodJavaVersion }
if RegQueryStringValue(HKLM, 'SOFTWARE\JavaSoft\Java Runtime Environment',
'CurrentVersion', JavaVer) AND (JavaVer <> '') OR
RegQueryStringValue(HKLM64, 'SOFTWARE\JavaSoft\Java Runtime Environment',
'CurrentVersion', JavaVer) AND (JavaVer <> '') then begin
Log('* Java Entry in Registry present. Version: ' + JavaVer);
isGoodJavaVersion := CompareStr(JavaVer, REQUIRED_JAVA_VERSION) >= 0;
end;
{ add additional checks, for example by searching the PATH, }
{ or by running `java -version` }
Result := isGoodJavaVersion;
end;
[Run]
Filename: "{tmp}\{#JavaInstaller}"; Parameters: "SPONSORS=0"; \
StatusMsg: "Java Runtime Enviroment not installed on your system. Installing..."; \
Check: not isJavaInstalled
Searches for 32 and 64 bit versions in registry, internal function CompareStr()
is actually usable for comparing versions in String,
you can change >= 0
to =0
if you want to check against the exact version and not 'at least'.
Alternatively Exec()
could be used instead of [Run]
, if you want to cancel the whole install in case when the user will not go through with the Java install by cancelling it or because of an error.
I changed your code a little, I think this way newer versions of Java will be supported ;-)
function InitializeSetup(): Boolean;
var
ErrorCode: Integer;
JavaInstalled : Boolean;
Result1 : Boolean;
Versions: TArrayOfString;
I: Integer;
begin
if RegGetSubkeyNames(HKLM, 'SOFTWARE\JavaSoft\Java Runtime Environment', Versions) then
begin
for I := 0 to GetArrayLength(Versions)-1 do
if JavaInstalled = true then
begin
//do nothing
end else
begin
if ( Versions[I][2]='.' ) and ( ( StrToInt(Versions[I][1]) > 1 ) or ( ( StrToInt(Versions[I][1]) = 1 ) and ( StrToInt(Versions[I][3]) >= 6 ) ) ) then
begin
JavaInstalled := true;
end else
begin
JavaInstalled := false;
end;
end;
end else
begin
JavaInstalled := false;
end;
//JavaInstalled := RegKeyExists(HKLM,'SOFTWARE\JavaSoft\Java Runtime Environment\1.9');
if JavaInstalled then
begin
Result := true;
end else
begin
Result1 := MsgBox('This tool requires Java Runtime Environment version 1.6 or newer to run. Please download and install the JRE and run this setup again. Do you want to download it now?',
mbConfirmation, MB_YESNO) = idYes;
if Result1 = false then
begin
Result:=false;
end else
begin
Result:=false;
ShellExec('open',
'http://www.java.com/getjava/',
'','',SW_SHOWNORMAL,ewNoWait,ErrorCode);
end;
end;
end;
end.
More enhancement for the already defined code:
Code:
function InitializeSetup(): Boolean;
var
ErrorCode: Integer;
JavaInstalled : Boolean;
ResultMsg : Boolean;
Versions: TArrayOfString;
I: Integer;
regRoot: Integer;
begin
// Check which view of registry should be taken:
regRoot := HKLM
begin
if IsWin64 then
begin
regRoot := HKLM64
end;
end;
if (RegGetSubkeyNames(regRoot, 'SOFTWARE\JavaSoft\Java Runtime Environment', Versions)) or (RegGetSubkeyNames(regRoot, 'SOFTWARE\JavaSoft\Java Development Kit', Versions)) then
begin
for I := 0 to GetArrayLength(Versions)-1 do
if JavaInstalled = true then
begin
//do nothing
end else
begin
if ( Versions[I][2]='.' ) and ( ( StrToInt(Versions[I][1]) > 1 ) or ( ( StrToInt(Versions[I][1]) = 1 ) and ( StrToInt(Versions[I][3]) >= 7 ) ) ) then
begin
JavaInstalled := true;
end else
begin
JavaInstalled := false;
end;
end;
end else
begin
JavaInstalled := false;
end;
if JavaInstalled then
begin
Result := true;
end else
begin
ResultMsg := MsgBox('Oracle Java v1.7 or newer not found in the system. Java 1.7 or later is required to run this application (can be installed after this installation too). Do you want to continue?',
mbConfirmation, MB_YESNO) = idYes;
if ResultMsg = false then
begin
Result := false;
end else
begin
Result := true;
ShellExec('open',
'http://www.java.com/getjava/',
'','',SW_SHOWNORMAL,ewNoWait,ErrorCode);
end;
end;
end;
end.
Instead of checking for a specific version, you can use
function RegKeyExists(const RootKey: Integer; const SubKeyName: String): Boolean;
to get the subkeys of HKLM\SOFTWARE\JavaSoft\Java Runtime Environment. (Is parallel installation of different versions possible? Don't know...) You would need to do some string fiddling to check if 1.6 or higher is installed, but it would be more flexible than checking for a specific version number.
For your third question, see here, under the Trademark and Licensing section. Exec summary: you can distribute the JRE along with your app. I think a few apps do this to ensure they do not have version compatibility issues - i.e install the JRE in a subfolder of the app itself.
As far as being in the PATH, why is that important? You can create a shortcut that refers to java.exe by its full path to run your app. Is it important that the user start the program via the command line themselves?
A simple alternative to the already proposed answers:
[Code]
function InitializeSetup(): boolean;
var
ResultCode: integer;
begin
if Exec('java', '-version', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin
Result := true;
end
else begin
if MsgBox('This tool requires Java Runtime Environment version 1.6 or newer to run. Please download and install the JRE and run this setup again. Do you want to download it now?', mbConfirmation, MB_YESNO) = idYes then begin
Result := false;
ShellExec('open', 'https://java.com/download/', '', '', SW_SHOWNORMAL, ewNoWait, ResultCode);
end;
end;
end;