要求
我想在 Windows 7 上发布 Java GUI 应用程序。该应用程序使用 Swing Toolkit,不需要任何本机代码。该应用程序是使用 NSIS 安装程序安装的。我想尽可能将此应用程序集成到 Windows 7 中。这意味着:
- 当应用程序运行时,必须能够将应用程序固定到任务栏。
- 必须能够将数据文件与应用程序关联起来,以便 Windows 使用我的应用程序打开这些文件。
- 必须自动与 32 位 Java 运行时和 64 位 Java 运行时配合使用。因此,当用户卸载 32 位 Java 并安装 64 位 Java 时(反之亦然),那么我的应用程序必须仍然可以工作。
- 必须支持Windows的大字体设置。我实在不太明白这个功能。我只知道有些应用程序完全忽略它,其他应用程序(例如 Google Chrome)是像素缩放的(看起来真的很难看),而其他应用程序则通过简单地按预期使用更大的字体来支持它(这就是我想要的,通常它可以工作。只有 WinRun4J 解决方案下面提到的不适用于它)。
经过测试的解决方案
WinRun4J
WinRun4j 是一个启动 Java 应用程序的 EXE 文件。因为应用程序不会派生新的 Java 进程,所以 Windows 认为 EXE 文件就是应用程序。所以任务栏没有问题。文件关联之所以有效,是因为文件可以简单地与 EXE 文件关联。
问题:
- 不支持大字体。应用程序窗口是像素缩放的(如 Google Chrome)。
- 根据安装的 JRE,必须使用两个不同的 EXE 文件。因此,当安装 64 位 JRE 时,应用程序必须使用 64 位 EXE 文件启动。当安装 32 位 JRE 时,必须使用其他 EXE。这对用户不太友好,因为用户不明白为什么在只安装了 32 位 JRE 的情况下必须在 64 位操作系统上使用 32 位 EXE。
Launch4J
Launch4J 创建一个 32 位 EXE,它启动外部 Java 进程来启动 Java 应用程序。因此,与 WinRun4J 不同的是,它还可以启动 64 位 Java。
问题:
- 无法将应用程序固定到任务栏。
- 如果
headerType="gui"
,则无论应用程序是否从控制台启动,System.out.println
都不会打印到控制台。
JAR
在 Windows 上,您只需双击 JAR 文件即可启动应用程序。安装JRE并不重要,只要工作就可以。但是...
问题:
- 应用程序无法固定到任务栏。
- 无法在开始菜单中创建快捷方式。
- 无法将文件与 JAR 文件关联。
BAT/CMD
像这样的简单批处理文件可用于启动应用程序:
@echo off
start c:\windows\system32\javaw.exe -jar "c:\program files\myapp\myapp.jar" %1
可以为此批处理文件创建快捷方式以设置自定义图标。
问题:
- 应用程序启动时会弹出 DOS 窗口。
- 批处理文件不知道 javaw.exe 位于何处。根据安装的 java 版本(32 位或 64 位),它可能位于
c:\windows\syswow64
中,并且 Windows 不会自动从批处理文件重定向此调用。使用 JAVA_HOME
环境变量也是不行的,因为 Java 不会自动设置它。
- 将文件与批处理文件关联时,无法设置自定义图标。
- 任务栏支持无法正常工作。当手动启动批处理文件时,应用程序可以固定到它,但是当双击关联文件时,它就不起作用。
快捷方式
可以只创建快捷方式来启动应用程序,而不是使用批处理文件。它链接到此命令:c:\windows\system32\javaw.exe -jar "c:\program files\myapp\myapp.jar"
。如果安装了 32 位 Java JRE,Windows 会自动将此调用重定向到 SysWOW64 目录。
问题:
- 无法将文件与其关联,因为 Windows 只接受 EXE/COM/PIF/BAT/CMD 文件作为关联目标。 LNK 文件不起作用。
问题
是否有另一种解决方案可以满足上述所有要求?或者有什么技巧可以解决上述解决方案中的问题吗?
解决方案
使用 Launch4j 解决任务栏固定问题后,看起来是最好的解决方案。 Launch4j 可以轻松集成到 Maven 项目中(使用 this 或 这个插件),配置非常简单,一切正常除任务栏固定之外的框。对于任务栏固定,Java 应用程序必须设置 appModelUserId,如 this 的答案中所述问题。
此外,Java 应用程序必须由安装程序安装,该安装程序必须至少安装一个指向 EXE 的快捷方式。此快捷方式还必须包含 appModelUserId。对于 NSIS,这可以通过 WinShell 插件 和如下配置来完成:
CreateShortCut "$SMPROGRAMS\MyApp.lnk" \
"$INSTDIR\myapp.exe" "" "$INSTDIR\myapp.exe" 0 SW_SHOWNORMAL
WinShell::SetLnkAUMI "$SMPrograms\MyApp.lnk" "MyAppModelUserId"
出于某种未知原因这个快捷方式只需要存在即可。你不必使用它。您可以双击 EXE,任务栏固定仍然有效。您甚至可以在应用程序文件夹的某些子文件夹中创建快捷方式。当 EXE 文件的最后一个快捷方式被删除时,任务栏固定将停止工作。
Requirements
I want to publish a Java GUI application on Windows 7. This application is using the Swing Toolkit and doesn't need any native code. The application is installed using an NSIS installer. I want to integrate this application into Windows 7 as good as possible. This means:
- When the application is running it must be possible to pin the application to the taskbar.
- It must be possible to associate data files with the application so Windows opens these files with my application.
- Must automatically work with the 32 bit Java Runtime and with the 64 bit Java runtime. So when the user uninstalls a 32 bit Java and installs a 64 bit Java instead (Or vice-versa) then my application must still work.
- Must support large fonts setting of Windows. I don't really understand this feature. I just know that some applications ignore it completely, others (Like Google Chrome) are pixel-scaled (Looks really ugly) and others support it by simply using larger fonts as intended (That's what I want and normally it works. Only the WinRun4J solution mentioned below doesn't work with it).
Tested solutions
WinRun4J
WinRun4j is an EXE file which launches the Java application. Because the application doesn't fork a new Java process Windows thinks the EXE file IS the application. So there is no problem with the taskbar. File associations works because the files can be simply associated with the EXE file.
Problems:
- Doesn't support large fonts. Application window is pixel-scaled instead (Like Google Chrome).
- Two different EXE files must be used depending on the installed JRE. So when the 64 bit JRE is installed then the application must be started with the 64 Bit EXE file. When 32 bit JRE ins installed then the other EXE must be used. This isn't user-friendly because the user doesn't understand why he must use the 32 bit EXE on a 64 bit operating system when only a 32 bit JRE is installed.
Launch4J
Launch4J creates a 32 bit EXE which launches an external Java process to start the Java application. So unlike WinRun4J it can also start a 64 bit Java.
Problems:
- Can't pin the application to the taskbar.
System.out.println
will not print to console if headerType="gui"
, regardless if application is started from console.
JAR
On Windows you can simply double click the JAR file to start the application. Installed JRE doesn't matter, simply works. But...
Problems:
- Application can't be pinned to the taskbar.
- Can't create a shortcut in the start menu.
- Can't associate files with a JAR file.
BAT/CMD
A simple batch file like this can be used to start the application:
@echo off
start c:\windows\system32\javaw.exe -jar "c:\program files\myapp\myapp.jar" %1
A shortcut can be created for this batch file to set a custom icon.
Problems:
- A DOS window pops up when the application is started.
- The batch file doesn't know where javaw.exe is located. Depending on which java version (32 or 64 bit) is installed it may be located in
c:\windows\syswow64
instead and Windows doesn't redirect this call from batch files automatically. Using the JAVA_HOME
environment variable is also a no-go because Java doesn't set this automatically.
- When associating files with the batch file then no custom icon can be set.
- Taskbar support isn't working properly. Application can be pinned to it when the batch file is started manually but when double clicking an associated file instead then it doesn' work.
Shortcut
Instead of using a batch file it is possible to only create a shortcut to start the application. It links to this command: c:\windows\system32\javaw.exe -jar "c:\program files\myapp\myapp.jar"
. Windows automatically redirects this call to the SysWOW64 directory if a 32 bit Java JRE is installed.
Problems:
- Not possible to associate files with it because Windows only accepts EXE/COM/PIF/BAT/CMD files as association targets. LNK files don't work.
Question
Is there another solution which fulfills all the requirements from above? Or are there any tricks to solve the problems with the mentioned solutions?
Solution
After solving the taskbar-pinning problem using Launch4j looks like the best solution. Launch4j can easily be integrated into a Maven project (With this or this plugin), configuration is pretty easy and everything works out of the box except taskbar pinning. For taskbar-pinning the Java application must set an appModelUserId as explained in the answer to this question.
Additionally the Java application must be installed by an installer which must at least install one shortcut pointing to the EXE. This shortcut must also contain the appModelUserId. With NSIS this can be done with the WinShell plugin and a configuration like this:
CreateShortCut "$SMPROGRAMS\MyApp.lnk" \
"$INSTDIR\myapp.exe" "" "$INSTDIR\myapp.exe" 0 SW_SHOWNORMAL
WinShell::SetLnkAUMI "$SMPrograms\MyApp.lnk" "MyAppModelUserId"
For some unknown reason this shortcut only has to exist. You don't have to use it. You can double-click the EXE and taskbar-pinning still works. You can even create the shortcut in some subfolder of your application folder. Taskbar-pinning stops working when the last shortcut of the EXE file is removed.
发布评论
评论(5)
尝试 Launch4j (http://launch4j.sourceforge.net/),它是一个简单的 jar 到 exe 包装器(实际上包装 jar 是可选的)。它应该可以解决您的图标和任务栏要求。它还能够定位已安装的 JRE(一些可配置的规则)。我不太明白的字体问题,Swing 应该根据 Windows 设置自动使用字体,除非您以某种方式在 JRE 选项或代码中覆盖该字体。
Try Launch4j (http://launch4j.sourceforge.net/), its a simple jar to exe wrapper (actually wrapping the jar is optional). It should solve your Icon and Taskbar requirements. Its also capable locating installed JRE's (some configurable rules). The font problem I don't quite get, Swing should automatically use fonts depending on Windows settings, unless you somehow overwrite that in the JRE options or in code.
Java Web Start - 如今,我不会考虑以任何其他方式分发应用程序。
用户确实需要至少有J2SE 1.4;如果您的应用程序需要更高版本,Web Start 将自动下载合适的 JRE。
有关标记,请参阅 JNLP 参考用于桌面集成(
快捷方式
和允许离线
)和文件关联(关联
)。但这些仅在 WS 1.5 中受支持。Java Web Start - I wouldn't consider distributing an application any other way, these days.
The user does need to have at least J2SE 1.4; if your applications needs a later version, Web Start will automatically download an appropriate JRE.
See the JNLP reference for the tags for desktop integration (
shortcut
andoffline-allowed
), and file associations (association
). These are only supported in WS 1.5 though.我个人使用 Launch4j(更准确地说,通过带有 maven-launch4j-plugin 的 Maven),并且我在我的应用程序中实现了系统托盘管理...(参见 http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/systemtray/)。
I personaly use Launch4j (through maven with the maven-launch4j-plugin to be even more precise), and I implement the system tray management from within my application... (See http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/systemtray/).
总的来说,我在 WinRun4J 方面取得了很好的成功,但我在字体方面并没有真正做太多工作,所以我承认我不确定我是否理解为什么你会遇到你在那里描述的问题。
然而,根据您的描述,您似乎对 Java 本机启动器有非常具体的要求。为什么不自己写呢?您可以从 WinRun4J(它是开源的,在 Eclipse CPL 下获得许可)之类的东西开始,然后根据您的需要对其进行修改。
或者,您可以查看其他程序使用的本机启动器。 Eclipse 和 NetBeans 启动器似乎都工作得很好,而且都是开源的。您也许也可以很容易地适应其中之一。
I've had good success with WinRun4J overall, but I haven't really done much with fonts, so I'll confess I'm not sure I understand why you're having the issue you describe there.
From what you describe, however, it sounds like you have very specific requirements from a Java native launcher. Why not just write your own? You could start with something like WinRun4J (which is open source, licensed under the Eclipse CPL) and just modify it to your needs.
Alternatively, you could look into the native launchers used by other programs. The Eclipse and NetBeans launchers both seem to work pretty well, and both are open source. You might be able to adapt one of them pretty easily as well.
顺便说一句,还可以查看将您的应用程序放在工具托盘/系统托盘中的新功能:
Oracle 有一个 关于如何使用系统托盘的教程。
这与 Java SE 6 相关......让我想知道较新的 Java 7 中可能还有哪些其他优点?
As an aside, also check out the new feature to have your app in the tooltray/systemtray:
Oracle has a tutorial on how to use the system tray.
That's Java SE 6 related....makes me also winder what other goodies might be in the newer Java 7?