36

我是 Java 编程新手,但通常熟悉一切工作原理。我希望能够将 jar 文件和 jre 都放入 windows 可执行文件(exe)中,这样当我分发它时,客户端就不需要安装 JRE。我应该使用什么程序?

我有launch4j,它似乎完全符合我的要求,但是当我尝试运行该应用程序时,我得到“此应用程序配置为使用捆绑的Java运行时环境,但运行时丢失或损坏。”

我希望我的应用程序只是一个可运行的 exe,而不是安装程序。至少,谁能告诉我如何正确地将 JRE 与 launch4j 捆绑在一起?

4

9 回答 9

43

我可以捆绑 JRE 的唯一方法是使用Launch4JInno Setup Compiler

首先,在与输出文件 (.exe) 相同的目录中创建一个jre6文件夹(例如)。

然后将 JRE 从您的系统复制到您的jre6文件夹中。

然后打开 Launch4J 并设置Bundled JRE 路径- 只需输入jre6. 然后单击 Build 按钮(显然,在您输入所有其他参数之后 - 但您需要在JRE选项卡本身上输入的唯一值是Bundled JRE 路径值。)

我原以为这会起作用,但是如果您随后将 .exe 移动到新位置(因此它不再与您的jre6文件夹位于同一位置),您会得到此应用程序配置为使用捆绑的 Java 运行时环境,但是当您尝试运行应用程序时,运行时丢失或损坏错误...

我整天都在玩这个,我无法让Launch4J将 JRE 包含在 .exe 文件中。在我看来真的很差,因为他们的文档似乎根本没有提到这个问题。

所以我要解决的是使用Inno Setup Compiler (ISC)。此应用程序用于将您的 .exe 包装为 Windows Installer 文件。所以我在 ISC 脚本中添加了一个设置,将 JRE 复制到安装程序包中。我添加到脚本中的行(在该[Files]部分中)是:

Source: "M:\Netbeans\MyApp\jre6\*"; DestDir: "{app}\jre6\"; Flags: recursesubdirs createallsubdirs

...一些解决方法,但它成功了。

重复上述所有步骤,您应该被排序。

于 2013-03-25T16:44:32.887 回答
6

将 jre 打包为 lanch4j 打包的 exe 的简单方法是使用 wrap。

warp-packer --arch windows-x64 --input_dir mycrt --exec run.bat --output single.exe

然后在启动 exe 时停止 cmd 窗口。

editbin /subsystem:windows

经线https ://github.com/dgiagio/warp

editbin : 由 VS 安装

演示:

在此处输入图像描述

在此处输入图像描述

于 2019-04-13T06:13:12.327 回答
3

用于 Inno Setup 的捆绑 JRE 解决方案

为了使用应用程序 jar 实现捆绑的 JRE 解决方案,我创建了一个 Inno Setup 脚本:

1)将JRE复制到安装exe中

2) 执行等效的终端命令: java -jar myjar.jar 使用捆绑的 JRE

首先我复制JRE:

#define MyJREPath "C:\Program Files\Java\jre1.8.0_191"

[Files]
Source: "{#MyJREPath}\*"; DestDir: "{app}\runtime\jre\";  \
        Flags: ignoreversion recursesubdirs createallsubdirs;  

我遵循此处显示的目录结构约定:https ://docs.oracle.com/javase/8/docs/technotes/guides/deploy/self-contained-packaging.html

运行 java -jar myjar.jar 的等效项:

[Run]
Filename: "{app}\runtime\jre\bin\javaw.exe"; Parameters: " -jar myjar.jar"; \
          WorkingDir: "{app}\app\"; \
          Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \
          Flags: postinstall skipifsilent   

(nb java.exe 使用终端运行,javaw.exe 不使用终端运行)

桌面快捷方式需要有正确的文件名、参数和工作目录:

[Icons]
Name: "{commondesktop}\{#MyAppName}"; \
      IconFilename: "{app}\app\{#MyAppIcoName}"; \
      Filename: "{app}\runtime\jre\bin\javaw.exe"; \
      Parameters: " -jar myjar.jar"; \
      WorkingDir: "{app}\app\"; \
      Tasks: desktopicon

[Tasks]
Name: "desktopicon"; \
    Description: "{cm:CreateDesktopIcon}"; \
    GroupDescription: "{cm:AdditionalIcons}"; \
    Flags: unchecked

锦上添花,为了让我的脚本同时处理捆绑的 JRE 和非捆绑的选项,我使用预处理器 IF 语句(在每个脚本部分中重复)来测试脚本是否有空的 MyJREPath。如果 MyJREPath 不为空,因此需要捆绑的 JRE 解决方案,我使用上面的编码;或者,如果不需要捆绑解决方案,那么我使用更多“正常”编码显示 Inno Setup 示例或由他们的向导生成。这是 IF 语句:

#if MyJREPath != ""
    ; bundled JRE required

#else
    ; bundled JRE not required
#endif

这是我的大部分脚本放在一起:

        ; Script generated by the Inno Setup Script Wizard.
        ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!


        ; some more #defines here

        #define MyAppExeName "javaw.exe"
        #define MyJREPath "C:\Program Files\Java\jre1.8.0_191" 
        ;#define MyJREPath ""




        [Setup]
        ; NOTE: The value of AppId uniquely identifies this application.
        ; Do not use the same AppId value in installers for other applications.
        ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
        AppId=XXXXXXXXXX
        AppName={#MyAppName}
        AppVersion={#MyAppVersion}
        ;AppVerName={#MyAppName} {#MyAppVersion}
        AppPublisher={#MyAppPublisher}
        DefaultGroupName={#MyAppPublisher}
        AppPublisherURL={#MyAppURL}
        AppSupportURL={#MyAppURL}
        AppUpdatesURL={#MyAppURL}   
        DefaultDirName={pf}\{#MyDefaultDirName}
        DisableProgramGroupPage=yes
        LicenseFile={#MyInnoSetupDir}\system\{#MyLicenseFile}
        OutputDir={#MyInnoSetupDir}

        #if MyJREPath != "" 
          ; run app with bundled JRE
          OutputBaseFilename={#MyAppName}-{#MyAppVersion}-bundledJRE-setup
        #else
          ; run app without bundled JRE
          OutputBaseFilename={#MyAppName}-{#MyAppVersion}-setup          
        #endif 

        SetupIconFile={#MyInnoSetupDir}\{#MyAppIcoName}
        Compression=lzma
        SolidCompression=yes  
        AppComments={#MyAppName}
        AppCopyright={#MyAppCopyright}  
        UninstallDisplayIcon={#MyInnoSetupDir}\{#MyAppIcoName}
        UninstallDisplayName={#MyAppName}
        WizardImageStretch=No
        WizardSmallImageFile={#MyInnoSetupDir}\{#MyAppBmpName}



        [Languages]
        Name: "english"; MessagesFile: "compiler:Default.isl"
        ;Name: "german"; MessagesFile: "compiler:Languages\German.isl"

        [Tasks]
        Name: "desktopicon"; \
                Description: "{cm:CreateDesktopIcon}"; \
                GroupDescription: "{cm:AdditionalIcons}"; \
                Flags: unchecked
        Name: "quicklaunchicon"; \
                Description: "{cm:CreateQuickLaunchIcon}"; \
                GroupDescription: "{cm:AdditionalIcons}"; \
                Flags: unchecked; OnlyBelowVersion: 0,6.1

        [Files]
        ; bundle JRE if required
        #if MyJREPath != "" 
            Source: "{#MyJREPath}\*"; DestDir: "{app}\runtime\jre\";  \
                Flags: ignoreversion recursesubdirs createallsubdirs;       
        #endif      

        ; copy jar and all files  
        Source: "{#MyInnoSetupDir}\*"; DestDir: "{app}\app\"; \        
                Flags: ignoreversion recursesubdirs createallsubdirs


        [Icons]
        #if MyJREPath != ""
          ; set up icons with bundled JRE
          Name: "{commonprograms}\{#MyAppName}"; \
                  IconFilename: "{app}\app\{#MyAppIcoName}"; \
                  Filename: "{app}\runtime\jre\bin\{#MyAppExeName}"; \
                  Parameters: " -jar {#MyJarName}"; \
                  WorkingDir: "{app}\app\"
          Name: "{commondesktop}\{#MyAppName}"; \
                  IconFilename: "{app}\app\{#MyAppIcoName}"; \
                  Filename: "{app}\runtime\jre\bin\{#MyAppExeName}"; \
                  Parameters: " -jar {#MyJarName}"; \
                  WorkingDir: "{app}\app\"; \
                  Tasks: desktopicon            
          Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; \
                  IconFilename: "{app}\app\{#MyAppIcoName}"; \
                  Filename: "{app}\runtime\jre\bin\{#MyAppExeName}"; \
                  Parameters: " -jar {#MyJarName}"; \
                  WorkingDir: "{app}\app\"; \
                  Tasks: quicklaunchicon
        #else
          ; set up icons without bundled JRE
          Name: "{commonprograms}\{#MyAppName}"; \
                  IconFilename: "{app}\app\{#MyAppIcoName}"; \
                  Filename: "{app}\app\{#MyJarName}"; \
                  WorkingDir: "{app}\app\"
          Name: "{commondesktop}\{#MyAppName}"; \
                  IconFilename: "{app}\app\{#MyAppIcoName}"; \
                  Filename: "{app}\app\{#MyJarName}"; \
                  WorkingDir: "{app}\app\"; \
                  Tasks: desktopicon            
          Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; \
                  IconFilename: "{app}\app\{#MyAppIcoName}"; \
                  Filename: "{app}\app\{#MyJarName}"; \
                  WorkingDir: "{app}\app\"; \
                  Tasks: quicklaunchicon 
        #endif

        [Run]
        #if MyJREPath != ""
          ; run app with bundled JRE
          Filename: "{app}\runtime\jre\bin\{#MyAppExeName}"; Parameters: " -jar {#MyJarName}"; \
                  WorkingDir: "{app}\app\"; \
                  Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \
                  Flags: postinstall skipifsilent          
        #else
          ; run app without bundled JRE
          Filename: "{app}\app\{#MyJarName}"; \
                  WorkingDir: "{app}\app\"; \
                  Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; \
                  Flags: shellexec postinstall skipifsilent          
        #endif 

希望这可以帮助。

于 2018-12-13T21:28:06.613 回答
2

我从来没有使用过 Launch4J 产品,祝它配置正确。

看起来你可以去 Sourceforge 上的论坛获取其他提示

其他建议:

我从 IBM (Websphere) 和 Oracle 看到的大多数产品只是在安装目录下提取一个 JRE,并配置启动批处理命令以使用已安装的 JRE。本质上,JRE 和您的 jar 文件将一次性安装。

安装 exe 通常会检查它是否已经安装,如果发现它已经存在则跳过该步骤。这对于仅升级 jar 文件很有用。

本地安装还解决了客户安装自己的 JRE 的问题,这些 JRE 可能不兼容或包含错误。这样您就可以处理已知的 JRE 版本。

如果您的应用程序没有图形组件,则 excelsior 路线是可以的(已经有一段时间了,该限制可能已经改变)。还有其他限制,但您最好将 JRE 与您的代码一起分发到单个可执行安装程序中。

于 2012-12-21T21:17:17.960 回答
2

JDK 7 Update 6 中的 JDK 随附的 Java Packager 是将 JRE 与您的代码一起嵌入到本机可执行文件中 的官方方式。一些maven插件似乎打包了主要平台打包生成本机可执行文件的任务。

从 JDK11 需要根据java-packager-with-jdk11下载 java 打包程序,女巫演示使用 gradle 进行打包

另一种方法可能是构建一个带有约束的GraalVM Native 映像,以使用不受支持的反射来查找库的替代方案。

于 2020-04-26T10:02:45.827 回答
1

很容易将 jre 捆绑到 launch4j 中。

只需将 jre 复制到相同的输出文件夹中

在bundle jre环境文本框中,只给jre文件夹本身

在环境变量文本框中(在下面的同一页中),给出直到 bin

然后创建exe ..它在机器中没有jre的情况下按预期工作。

谢谢

于 2018-02-05T11:47:39.647 回答
0

看来您需要本机代码编译器。这些编译器生成不需要 JRE 的本机代码。

检查这篇文章 - https://www.excelsior-usa.com/articles/java-to-exe.html#aot

于 2012-12-21T21:05:03.893 回答
-3

launch4j 不能顺利运行有几个原因。部分原因是:

1) 用户不要以管理员身份运行应用程序

2) 用户没有正确设置图标图像。必须严格.ico

于 2014-05-15T02:46:25.467 回答
-3

你所要求的并不容易做到(如果它完全可行的话。)如果我是你,我会考虑创建一个可执行的 JAR 文件:

java eclipse 创建可执行jar

另一种选择是使用 Java Web Start。这是假设您使用的是现代浏览器,JNLP 将自动提示用户安装正确版本的 Java。

http://docs.oracle.com/javase/tutorial/deployment/webstart/index.html

于 2012-12-21T20:12:29.003 回答