要求
我想在 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。
发射4J
Launch4J创建一个 32 位 EXE,它启动一个外部 Java 进程来启动 Java 应用程序。因此,与 WinRun4J 不同的是,它还可以启动 64 位 Java。
问题:
- 无法将应用程序固定到任务栏。
System.out.println
headerType="gui"
如果,无论应用程序是否从控制台启动,都不会打印到控制台。
罐
在 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 项目中(使用这个或这个插件),配置非常简单,除了任务栏固定之外,一切都是开箱即用的。对于任务栏固定,Java 应用程序必须设置一个 appModelUserId,如该问题的答案中所述。
此外,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 文件的最后一个快捷方式后,任务栏固定停止工作。