2009-08-19 184 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安裝或因錯誤進行安裝。