Перед установкой проверьте наличие Java
Я создаю установщик Inno Setup для приложения jar.
Сейчас я хочу проверить, присутствует ли Java, прежде чем приступать к установке. Поэтому мне нужно только убедиться, что пользователи смогут запускать:
java -jar my-app.jar
Сейчас я делаю следующее:
[Code]
function InitializeSetup(): Boolean;
var
ErrorCode: Integer;
JavaInstalled : Boolean;
Result1 : Boolean;
begin
JavaInstalled := RegKeyExists(HKLM,'SOFTWARE\JavaSoft\Java Runtime Environment\1.6');
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://javadl.sun.com/webapps/download/AutoDL?BundleId=33787',
'','',SW_SHOWNORMAL,ewNoWait,ErrorCode);
end;
end;
end;
end;
Мои вопросы:
-
Проверяет ли реестр достаточно, чтобы убедиться, что java home dir будет в PATH? (чтобы иметь возможность запускать "java" в консоли)
-
Если установлена более высокая версия java, будет ли такой ключ в реестре в любом случае, или мне нужно будет проверить, доступна ли каждая более высокая версия?
-
Есть ли у кого-нибудь лучший способ загрузить java, чем просто показывать всплывающее окно и переносить пользователей на страницу загрузки?
Ответы
Ответ 1
Я надеюсь, что кто-то найдет это полезным, то, что я сделал, - это повторное использование некоторого фрагмента кода, размещенного в вики Inno Setups, чтобы сделать < > сравнение с версией как число:
{ Both DecodeVersion and CompareVersion functions where taken from the wiki }
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;
{ Here my code }
function InitializeSetup(): Boolean;
var
ErrorCode: Integer;
JavaVer : String;
Result1 : Boolean;
begin
RegQueryStringValue(HKLM, 'SOFTWARE\JavaSoft\Java Runtime Environment', 'CurrentVersion', JavaVer);
Result := false;
if Length( JavaVer ) > 0 then
begin
if CompareVersion(JavaVer,'1.6') >= 0 then
begin
Result := true;
end;
end;
if Result = false then
begin
Result1 := MsgBox('This tool requires Java Runtime Environment v1.6 or older to run. Please download and install JRE and run this setup again.' + #13 + #10 + 'Do you want to download it now?',
mbConfirmation, MB_YESNO) = idYes;
if Result1 = true then
begin
ShellExec('open',
'http://www.java.com/en/download/manual.jsp#win',
'','',SW_SHOWNORMAL,ewNoWait,ErrorCode);
end;
end;
end;
Спасибо всем за вашу помощь
Ответ 2
Я немного изменил свой код, я думаю, что таким образом поддерживаются более новые версии Java; -)
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.
Ответ 3
Для вашего третьего вопроса см. здесь в разделе "Торговый знак и лицензирование". Резюме Exec: вы можете распространять JRE вместе со своим приложением. Я думаю, что несколько приложений делают это, чтобы убедиться, что у них нет проблем с совместимостью версий - установите JRE в подпапку самого приложения.
Что касается PATH, почему это важно? Вы можете создать ярлык, который ссылается на java.exe по его полному пути для запуска вашего приложения. Важно ли, чтобы пользователь запускал программу самостоятельно через командную строку?
Ответ 4
Улучшение для уже определенного кода:
- Проверьте наличие JRE/JDK.
- Проверить в 32-битном или 64-битном представлении реестра.
код:
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.
Ответ 5
Теперь есть другой способ. Вы можете включить Настройка Stub - онлайн-установщик, который будет загружать и устанавливать фактическую настройку.
Имя имени файла на данный момент равно JavaSetup8u121.exe
, что предполагает, что он может быть специфичным для версии. У меня нет старшего, чтобы проверить, будет ли он загружать фактическую или конкретную более старую версию.
И на данный момент, похоже, он устанавливает только 32-битную 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
Ищет 32 и 64-разрядные версии в реестре, внутренняя функция CompareStr()
действительно пригодна для сравнения версий в String,
вы можете изменить >= 0
на =0
, если хотите проверить точную версию, а не "по крайней мере".
В качестве альтернативы Exec()
можно использовать вместо [Run]
, если вы хотите отменить всю установку в случае, если пользователь не будет проходить через установку Java, отменив ее или из-за ошибки.
Ответ 6
Простая альтернатива уже предложенным ответам:
[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;
Ответ 7
Вместо проверки конкретной версии вы можете использовать
function RegKeyExists(const RootKey: Integer; const SubKeyName: String): Boolean;
чтобы получить подразделы HKLM\SOFTWARE\JavaSoft\Java Runtime Environment. (Возможно ли параллельная установка разных версий? Не знаю...) Вам нужно будет выполнить некоторую строчку, чтобы проверить, установлен ли 1.6 или выше, но это было бы более гибким, чем проверка определенного номера версии.