【问题标题】:How do I install a JRE from an Inno Setup?如何从 Inno Setup 安装 JRE?
【发布时间】:2014-07-25 20:57:38
【问题描述】:

我正在尝试通过 Inno Setup(以及另一个应用程序)安装最新的平台(x64 或 x86)适当的 Java 运行时环境。我找到了一些脚本示例,说明如何检测版本并在正确时进行安装并根据我的需要进行调整,但我一直遇到这种情况:

无法打开文件“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 安装程序从此脚本安装文件运行?

【问题讨论】:

  • 您的[Run] 部分似乎很奇怪。您使用了postinstall,它在最后一页上创建了复选框,这对于安装先决条件是非常不寻常的。但更糟糕的是,您运行该设置的{temp} 文件夹应该在安装程序完成时被删除。不要让用户运行应用程序。从 Inno Setup 安装程序的临时文件夹中。更好地使用PrepareToInstall 事件来安装先决条件。
  • 是的,你是对的。我不知道那个(安装后)选项到底做了什么。我也发现了这个问题。

标签: java permissions inno-setup permission-denied


【解决方案1】:

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

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 选项,但这目前有效。

【讨论】:

  • 当您省略postinstall 标志时,您不需要使用runascurrentuser 标志,因为它是默认使用的。
【解决方案2】:

根据最初的问题“我如何从 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;

您可能需要将 Enabled 值替换为 1 并将 Disabled 值替换为 0 如果 Java 运行时安装程序无法正常工作。这样做我没有遇到任何问题。无论如何,如果您想查看,请在代码中使用 Oracle 链接添加注释。

最后,很遗憾我们无法以任何方式收到 JRE 的安装进度状态,所以我们显示一条消息和一个进度条,让用户不会有安装程序挂起的感觉。 为此,我们保存之前的状态,使用标志 ewWaitUntilTerminated 执行Exec,等待安装完成后再继续我们的安装,一旦函数执行,我们就会恢复之前的状态已经结束了。

【讨论】:

  • +1 - 虽然 1) [Run] 部分与问题有什么关系? 2)您坚持对[Files] 部分进行特定排序的原因是什么? 3)你应该测试ResultCode &lt;&gt; 0,即使Exec返回true。
  • 我想知道Source: "Myprog.exe"; DestDir: "{app}"; Flags: ignoreversion 对我来说,该应用程序(程序)已以某种方式转换为 Windows 本机可执行文件。那是怎么做到的?我一直在使用 NetBeans Native 部署选项,但它包含了 JRE。如果是这样,似乎有一些皮带和牙套。为什么不直接使用 MyProg.jar?有必要设置文件关联,但我相信 jar 文件会运行得很好。我在这里有点新手,仍在苦苦挣扎,所以也许有人可以帮助我更好地理解。
  • 嗨@EdS 感谢您的评论。是的,我已经使用 Wrapper Launch4J [链接](www.launch4j.sourceforge.net) 转换了 jar 文件,但您当然可以分发 jar 文件(和lib 目录中的相关文件),甚至还有一个 bat 文件、Icon 文件等。问候
  • @MartinPrikryl 感谢您的评论,让我从上一个问题开始回复您。是的,测试 ResultCode var 更有用,因为它的细节更丰富,但对于这个示例来说,足以评估 Exec 的结果。 2 问题 - 为什么:如果 JRE 的安装出现问题,程序必不可少,例如,我们可以取消安装,从而取消安装顺序。 1 运行部分,一旦我成功完成安装,我就会在那里运行我需要的一切。问候
  • 3) 但如果 Exec 无法运行安装程序,则仅返回 False。如果安装程序启动,但安装失败,Exec 返回 true,但退出代码将指示安装失败。 2)但是你应该展示,如何中止/回滚安装,否则订购无效。 1)但这与问题无关。我看起来很困惑。
猜你喜欢
  • 2023-03-18
  • 1970-01-01
  • 2011-07-04
  • 2022-01-24
  • 1970-01-01
  • 2020-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多