如何从Inno Setup安装JRE?

时间:2014-07-25 20:57:39

标签: java permissions inno-setup permission-denied

我正在尝试通过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 < 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;

function InstallJava() : Boolean;
var
  ErrCode: Integer;
  JVer: String;
  InstallJ: Boolean;
begin
  RegQueryStringValue(
    HKLM, 'SOFTWARE\JavaSoft\Java Runtime Environment', 'CurrentVersion', JVer);
  InstallJ := true;
  if Length( JVer ) > 0 then
  begin
    if CompareVersion(JVer, '1.8') >= 0 then
    begin
      InstallJ := false;
    end;
  end;
  Result := InstallJ;
end;

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

2 个答案:

答案 0 :(得分:7)

我能够找出问题所在: 显然我在使用这些线条时错了:

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选项,但现在可以使用。

答案 1 :(得分:2)

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

我理解,如果目标计算机没有安装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;

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

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