代码之家  ›  专栏  ›  技术社区  ›  Santi

在安装之前检查Java

  •  19
  • Santi  · 技术社区  · 15 年前

    我正在为一个jar应用程序创建一个inno安装程序。 我现在想做的是检查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的家庭DIR将在路径中?(能够在控制台中运行“Java”)

    • 如果安装了更高版本的Java,那么注册表中的密钥是否仍然存在,或者我必须检查每个更高版本的可能吗?

    • 有没有比下载一个弹出窗口并把用户下载到下载页面更好的下载Java的方法?

    7 回复  |  直到 8 年前
        1
  •  14
  •   Martin Prikryl    8 年前

    我希望有人会发现这一点很有用,我所做的就是重用一些放在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;
    

    谢谢你的帮助

        2
  •  5
  •   jose.rob.jr    15 年前

    我稍微更改了代码,我认为这种方式将支持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
  •  3
  •   Martin Prikryl    8 年前

    现在有另一种方法。您可以包括 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安装或由于错误而无法进行Java安装。

        4
  •  2
  •   JimG    15 年前

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

    就在这条路上,为什么这很重要?您可以创建一个引用java.exe的快捷方式,通过它的完整路径来运行您的应用程序。用户通过命令行自己启动程序是否重要?

        5
  •  2
  •   Subhash Chandran    10 年前

    已定义代码的更多增强功能:

    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.
    
        6
  •  2
  •   varnaud    9 年前

    一个简单的替代方案:

    [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
  •  0
  •   Treb    15 年前

    您可以使用

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

    获取的子键 HKLM\Studio\JavaSoFT\Java运行环境 . (是否可以并行安装不同版本?不知道…)您需要做一些字符串修改来检查是否安装了1.6或更高版本,但是它比检查特定版本号更灵活。