Inno Setup,检测Java版本

在使用Inno Setup安装我的Java应用程序时,我希望安装程序检查是否存在Java 7或更高版本,并在需要时安装它。 但显然,我目前的代码无法在我的一些客户的计算机上检测到Java 8。 但是我无法重现这个bug。 你看到我可能遗失的东西吗? 也许这段代码不适用于最近的Windows?

基本上,我只是检查Java> = 1.7的注册表。

[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(ExpandConstant('{cm:JavaRequired}'), 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; 

编辑:这是基于马丁答案的最终结果。

 [Code] function CutJavaVersionPart(var V: string): Integer; var S: string; P: Integer; begin if Length(V) = 0 then begin Result := 0; end else begin P := Pos('.', V); if P = 0 then P := Pos('_', V); if P > 0 then begin S := Copy(V, 1, P - 1); Delete(V, 1, P); end else begin S := V; V := ''; end; Result := StrToIntDef(S, 0); end; end; function MaxJavaVersion(V1, V2: string): string; var Part1, Part2: Integer; Buf1, Buf2: string; begin Buf1 := V1; Buf2 := V2; Result := ''; while (Result = '') and ((Buf1  '') or (Buf2  '')) do begin Part1 := CutJavaVersionPart(Buf1); Part2 := CutJavaVersionPart(Buf2); if Part1 > Part2 then Result := V1 else if Part2 > Part1 then Result := V2; end; end; function GetJavaVersion(): string; var TempFile: string; ResultCode: Integer; S: AnsiString; P: Integer; begin TempFile := ExpandConstant('{tmp}\javaversion.txt'); if (not ExecAsOriginalUser( ExpandConstant('{cmd}'), '/c java -version 2> "' + TempFile + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)) or (ResultCode  0) then begin Log('Failed to execute java -version'); end else if not LoadStringFromFile(TempFile, S) then begin Log(Format('Error reading file %s', [TempFile])); end else if Copy(S, 1, 14)  'java version "' then begin Log('Output of the java -version not as expected'); end else begin Delete(S, 1, 14); P := Pos('"', S); if P = 0 then begin Log('Output of the java -version not as expected'); end else begin SetLength(S, P - 1); Result := S; end; end; DeleteFile(TempFile); end; function HasJava1Dot7OrNewer: Boolean; begin Result := (MaxJavaVersion('1.6.9', GetJavaVersion)  '1.6.9'); end; function InitializeSetup(): Boolean; var ErrorCode: Integer; begin Result := HasJava1Dot7OrNewer; if not Result then begin Result := MsgBox(ExpandConstant('{cm:JavaRequired}'), mbConfirmation, MB_YESNO) = idYes; if Result then begin ShellExec( 'open', 'https://www.java.com/getjava/', '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); end; end; end; 

我在HKLM\Software没有JavaSoft密钥。 我在HKLM\SOFTWARE\WOW6432Node有它。 什么是Inno Setup中的HKLM\SOFTWARE (32位应用程序)。

所以看起来你只需要删除if IsWin64 then regRoot := HKLM64块以使其正常工作。 或尝试两种选择。

 function CutJavaVersionPart(var V: string): Integer; var S: string; P: Integer; begin if Length(V) = 0 then begin Result := 0; end else begin P := Pos('.', V); if P = 0 then P := Pos('_', V); if P > 0 then begin S := Copy(V, 1, P - 1); Delete(V, 1, P); end else begin S := V; V := ''; end; Result := StrToIntDef(S, 0); end; end; function MaxJavaVersion(V1, V2: string): string; var Part1, Part2: Integer; Buf1, Buf2: string; begin Buf1 := V1; Buf2 := V2; Result := ''; while (Result = '') and ((Buf1 <> '') or (Buf2 <> '')) do begin Part1 := CutJavaVersionPart(Buf1); Part2 := CutJavaVersionPart(Buf2); if Part1 > Part2 then Result := V1 else if Part2 > Part1 then Result := V2; end; end; function GetJavaVersionFromSubKey(RootKey: Integer; SubKeyName: string): string; var Versions: TArrayOfString; I: Integer; begin if RegGetSubkeyNames(RootKey, SubKeyName, Versions) then begin for I := 0 to GetArrayLength(Versions) - 1 do begin Result := MaxJavaVersion(Result, Versions[I]); end; end; end; function GetJavaVersionFromRootKey(RootKey: Integer): string; begin Result := MaxJavaVersion( GetJavaVersionFromSubKey(RootKey, 'SOFTWARE\JavaSoft\Java Runtime Environment'), GetJavaVersionFromSubKey(RootKey, 'SOFTWARE\JavaSoft\Java Development Kit')); end; function GetJavaVersion: string; begin Result := GetJavaVersionFromRootKey(HKLM); if IsWin64 then begin Result := MaxJavaVersion(Result, GetJavaVersionFromRootKey(HKLM64)); end; end; 

根据您的特定需求,您可以检查是否安装了Java 1.7或更新版本,如下所示:

 function HasJava1Dot7OrNewer: Boolean; begin Result := (MaxJavaVersion('1.6.9', GetJavaVersion) <> '1.6.9'); end; 

或者你考虑过运行java -version吗?

 function GetJavaVersion2: string; var TempFile: string; ResultCode: Integer; S: AnsiString; P: Integer; begin TempFile := ExpandConstant('{tmp}\javaversion.txt'); if (not ExecAsOriginalUser( ExpandConstant('{cmd}'), '/c java -version 2> "' + TempFile + '"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)) or (ResultCode <> 0) then begin Log('Failed to execute java -version'); end else if not LoadStringFromFile(TempFile, S) then begin Log(Format('Error reading file %s', [TempFile])); end else if Copy(S, 1, 14) <> 'java version "' then begin Log('Output of the java -version not as expected'); end else begin Delete(S, 1, 14); P := Pos('"', S); if P = 0 then begin Log('Output of the java -version not as expected'); end else begin SetLength(S, P - 1); Result := S; end; end; DeleteFile(TempFile); end; 

更有效的InitializeSetup实现:

 function InitializeSetup(): Boolean; var ErrorCode: Integer; begin Result := HasJava1Dot7OrNewer; if not Result then begin Result := MsgBox(ExpandConstant('{cm:JavaRequired}'), mbConfirmation, MB_YESNO) = idYes; if Result then begin ShellExec( 'open', 'https://www.java.com/getjava/', '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode); end; end; end;