如何从Inno Setup安装JRE?

我正在尝试通过Inno Setup(以及其他应用程序)安装最新的平台(x64或x86)相应的Java Runtime Environment。 我找到了一些脚本示例,说明如何检测版本并安装如果正确并根据我的需要调整它们但我仍然遇到这样:

无法打开文件“path \ to \ JREInstall.exe”:
CreateProcess失败:代码5:
访问被拒绝

这是严格负责安装JRE的代码:

[Setup] AppName="JRE Setup" AppVersion=0.1 DefaultDirName="JRE Setup" [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" [Files] Source: "jre-8u11-windows-x64.exe"; DestDir: "{tmp}\JREInstall.exe"; \ Check: IsWin64 AND InstallJava(); Source: "jre-8u11-windows-i586.exe"; DestDir: "{tmp}\JREInstall.exe"; \ Check: (NOT IsWin64) AND InstallJava(); [Run] Filename: "{tmp}\JREInstall.exe"; Parameters: "/s"; \ Flags: nowait postinstall runhidden runascurrentuser; Check: InstallJava() [Code] 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  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  verint2[i] then Result := 1 else if verint1[i]  0 then begin if CompareVersion(JVer, '1.8') >= 0 then begin InstallJ := false; end; end; Result := InstallJ; end; 

在完整的设置脚本中,相同的消息继续出现。 如何从此脚本安装文件中运行JRE安装程序?

我能够弄明白这个问题:显然我在使用这些线时错了:

 Source: "jre-8u11-windows-x64.exe"; DestDir: "{tmp}\JREInstall.exe"; Check: IsWin64 AND InstallJava(); Source: "jre-8u11-windows-i586.exe"; DestDir: "{tmp}\JREInstall.exe"; Check: (NOT IsWin64) AND InstallJava(); 

他们应该像这样:

 Source: "jre-8u11-windows-x64.exe"; DestDir: "{tmp}"; DestName: "JREInstall.exe"; Check: IsWin64 AND InstallJava(); Source: "jre-8u11-windows-i586.exe"; DestDir: "{tmp}"; DestName: "JREInstall.exe"; Check: (NOT IsWin64) AND InstallJava(); 

这似乎解决了这个问题。

这条线我错了:

 Filename: "{tmp}\JREInstall.exe"; Parameters: "/s"; Flags: nowait postinstall runhidden runascurrentuser; Check: InstallJava() 

应该是:

 Filename: "{tmp}\JREInstall.exe"; Parameters: "/s"; Flags: nowait runhidden runascurrentuser; Check: InstallJava() 

这是我使用此特定工具的有限经验的最佳解决方案。 当我有机会时,我会查看PrepareToInstall选项,但现在可以使用。

根据最初的问题,“如何从Inno脚本安装JRE?”,并将最佳建议的解决方案作为起始解决方案,我提出了一个我认为更加连贯的解决方案。

据我所知,如果目标计算机没有安装Java运行时环境或者其版本低于所需的版本,则用户希望为其应用程序安装JRE。 好吧,我建议使用AfterInstall参数并以不同的方式重新排序分发文件。

我们将首先以另一种方式对[Files]部分中的文件进行排序,首先放置redist安装文件。

 Source: "redist\jre-8u121-windows-i586.exe"; DestDir: "{tmp}"; DestName: "JREInstaller.exe";\ Flags: deleteafterinstall; AfterInstall: RunJavaInstaller(); \ Check: (NOT IsWin64) AND InstallJava(); Source: "redist\jre-8u121-windows-x64.exe"; DestDir: "{tmp}"; DestName: "JREInstaller.exe"; \ Flags: deleteafterinstall; AfterInstall: RunJavaInstaller(); \ Check: IsWin64 AND InstallJava(); Source: "Myprog.exe"; DestDir: "{app}"; Flags: ignoreversion 

我们必须做的下一步是修改[Run]部分,如下所示。

 [Run] Filename: "{app}\{#MyAppExeName}"; \ Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \ Flags: nowait postinstall skipifsilent 

最后但并非最不重要的是,我们在[Code]部分中实现了RunJavaInstaller()过程,如下所示:

 [Code] procedure RunJavaInstaller(); var StatusText: string; ResultCode: Integer; Path, Parameters: string; begin Path := '{tmp}\JREInstaller.exe'; { http://docs.oracle.com/javase/8/docs/technotes/guides/install/config.html#table_config_file_options } Parameters := '/s INSTALL_SILENT=Enable REBOOT=Disable SPONSORS=Disable REMOVEOUTOFDATEJRES=1'; StatusText:= WizardForm.StatusLabel.Caption; WizardForm.StatusLabel.Caption:='Installing the java runtime environment. Wait a moment ...'; WizardForm.ProgressGauge.Style := npbstMarquee; try if not Exec(ExpandConstant(Path), Parameters, '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin { we inform the user we couldn't install the JRE } MsgBox('Java runtime environment install failed with error ' + IntToStr(ResultCode) + '. Try installing it manually and try again to install MyProg.', mbError, MB_OK); end; finally WizardForm.StatusLabel.Caption := StatusText; WizardForm.ProgressGauge.Style := npbstNormal; end; end; 

如果Java运行时安装程序无法正常工作,则可能需要将Enabled值替换为1 ,将Disabled值替换为0 。 这样做我没有遇到任何问题。 无论如何,如果你想看一下,你可以在代码中对Oracle链接进行评论。

最后,由于遗憾的是我们无法以任何方式接收JRE的安装进度状态,因此我们会显示一条消息和一个进度条,以便用户不会觉得安装程序已挂起。 为此,我们先保存状态,使用标志ewWaitUntilTerminated执行Exec ,等待该安装完成后再继续我们的操作,并在函数执行完成后恢复先前的状态。