安装前检查 Java 是否存在
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1297773/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Check Java is present before installing
提问by Santi
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 users will be able to run:
我正在为 jar 应用程序创建 Inno Setup 安装程序。我现在想做的是在继续安装之前检查 java 是否存在。所以我只需要确保用户能够运行:
java -jar my-app.jar
What I'm doing right now is:
我现在正在做的是:
[Code]
function InitializeSetup(): Boolean;
var
ErrorCode: Integer;
JavaInstalled : Boolean;
Result1 : Boolean;
begin
JavaInstalled := RegKeyExists(HKLM,'SOFTWARE\JavaSoft\Java Runtime Environment.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;
My questions are:
我的问题是:
Is checking the registry enough to be sure java's home dir will be in the PATH? (to be able to run "java" in the console)
If a higher version of java is installed, will that key in the registry exist anyway or I will have to check for each higher version possible?
Does anyone have a better way to download java than just showing a popup and taking the users to the download page?
检查注册表是否足以确保 java 的主目录将在 PATH 中?(为了能够在控制台中运行“java”)
如果安装了更高版本的 java,注册表中的那个键是否仍然存在,或者我将不得不检查每个可能的更高版本?
除了显示弹出窗口并将用户带到下载页面之外,有没有人有更好的下载 Java 的方法?
采纳答案by Santi
I hope someone finds this useful, what I did is reusing some piece of the code placed in Inno Setups wiki to make a < > comparison with the version as a number:
我希望有人觉得这很有用,我所做的是重用放置在 Inno Setups wiki 中的一些代码,将 < > 与版本作为数字进行比较:
{ 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's 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;
Thanks all for your help
感谢你的帮助
回答by JimG
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.
对于您的第三个问题,请参见此处的商标和许可部分。执行摘要:您可以将 JRE 与您的应用程序一起分发。我认为一些应用程序这样做是为了确保它们没有版本兼容性问题 - 即在应用程序本身的子文件夹中安装 JRE。
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?
至于在 PATH 中,为什么这很重要?您可以创建一个快捷方式,通过其完整路径引用 java.exe 来运行您的应用程序。用户自己通过命令行启动程序是否重要?
回答by Treb
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.
获取HKLM\SOFTWARE\JavaSoft\Java Runtime Environment 的子项。(是否可以并行安装不同版本?不知道...)您需要进行一些字符串调整以检查是否安装了 1.6 或更高版本,但这比检查特定版本号更灵活。
回答by jose.rob.jr
I changed your code a little, I think this way newer versions of Java will be supported ;-)
我稍微更改了您的代码,我认为这样将支持较新版本的 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.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.
回答by Subhash Chandran
More enhancement for the already defined code:
已定义代码的更多增强:
- Check for existence of JRE / JDK.
- Verify in either 32bit or 64bit view of registry.
- 检查 JRE/JDK 是否存在。
- 在注册表的 32 位或 64 位视图中进行验证。
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.
回答by varnaud
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;
回答by papo
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.
现在还有另一种方式。您可以包含一个存根安装程序 - 在线安装程序,它将下载并安装实际安装程序。
现在的文件名是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
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'.
在注册表中搜索 32 位和 64 位版本,内部函数CompareStr()
实际上可用于比较 String 中的版本,如果要检查确切版本而不是“至少” >= 0
,=0
则可以更改为。
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.
或者Exec()
可以用来代替[Run]
,如果你想取消的情况下,整个安装时,用户将不会与Java经过安装通过取消它,或者因为错误的。