2009-08-19 183 views
18

我正在为jar应用程序创建Inno Setup安装程序。 我现在想要做的是在继续安装之前检查java是否存在。所以我只需要确保用户将能够运行:安装前检查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的主目录将在PATH中? (能够在控制台上运行“java”)

  • 如果安装了更高版本的java,那么注册表中的该密钥是否会存在,或者我将不得不检查每个更高版本的可能性?

  • 有没有人有更好的方式来下载Java,而不仅仅是显示弹出窗口并将用户带到下载页面?

+2

您是否打算要求Sun Java,或者您是否打算允许任何版本(如BEA-erm,Oracle-JRokit)? – atk 2009-08-19 04:44:01

+0

不错的问题。我将坚持使用Sun Java,因为我的工具基于官方支持,而且由于不同的Java实现,我不想再面对未来的问题。 – Santi 2009-08-20 13:11:44

回答

13

我希望有人认为这有用的,我所做的是重用一些片放入的Inno设置维基的代码做一个<>与版本为数字比较:

{ 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; 

感谢所有为您帮助

+0

您的脚本是否支持安装JRE/JDK?许多用户获得Java,然后不安装JDK。 – YumYumYum 2012-03-03 20:33:13

2

对于第三个问题,请参阅商标和许可部分下的here。执行摘要:您可以将JRE与您的应用程序一起分发。我认为一些应用程序会这样做,以确保它们没有版本兼容性问题 - 即将JRE安装在应用程序本身的子文件夹中。

就PATH而言,为什么这很重要?您可以创建一个指向java.exe的快捷方式,以其完整路径运行您的应用程序。用户通过命令行自己启动程序很重要吗?

+0

我不想将整个JRE与我的应用程序捆绑在一起,它会给安装程序增加太多的权重,并且如果用户已经拥有它,则可能不必要。 第二个建议看起来不错。看起来我可以从注册表中找到从哪里获得java home dir ... – Santi 2009-08-19 05:06:29

+0

你有什么链接可以指导如何完成java.exe的完整路径吗? – rogerdpack 2013-06-17 22:16:31

0

不是检查特定的版本,你可以使用

function RegKeyExists(const RootKey: Integer; const SubKeyName: String): Boolean; 

得到HKLM \ SOFTWARE \ JavaSoft的\ Java运行时环境的子项。 (是否可以并行安装不同的版本?不知道...)您需要做一些字符串调试以检查是否安装了1.6或更高版本,但是它比检查特定版本号更灵活。

5

我改变你的代码一点,我认为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. 
2

更增强了alrea dy定义代码:

  1. 检查是否存在JRE/JDK。
  2. 验证注册表的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. 
+1

就我所见,您只添加了视图到不同的注册表根目录中。此外,你已经复制了所有在那里完成的错误代码...... – TLama 2014-06-22 09:12:26

+0

正如你所正确提到的,我将Win64机器中的检查添加到注册表根目录_HKLM64_。您没有注意到的是,检查现在包含路径_SOFTWARE \ JavaSoft \ Java Development Kit_。 – 2014-06-22 13:44:41

1

一个简单的替代已经提出了答案:

[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; 
+0

这是否检查特定版本的Java?如果发现1.5,该怎么办? – Snake 2016-05-31 12:16:29

2

现在有另一种方式。您可以包含一个Stub setup - online installer,它将下载并安装实际设置。
现在的文件名称是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()实际上是在字符串, 比较的版本,您可以更改>= 0=0可用的,如果你想核对准确的版本,而不是“至少”。

或者Exec()可以用来代替[Run],如果您想要取消整个安装,以防用户不能通过取消Java安装或因错误进行安装。