需求
我希望在Windows 7上发布一个Java GUI应用程序。该应用程序使用Swing工具包,不需要任何本地代码。该应用程序使用NSIS安装程序进行安装。我希望尽可能好地将此应用程序集成到Windows 7中。这意味着:
- 当应用程序正在运行时,必须能够将应用程序固定到任务栏。
- 必须能够将数据文件与应用程序关联,以便Windows使用我的应用程序打开这些文件。
- 必须自动适配32位Java Runtime和64位Java Runtime。因此,当用户卸载32位Java并安装64位Java(或反之亦然)时,我的应用程序仍然必须正常工作。
- 必须支持Windows的大字体设置。我真的不了解这个功能。我只知道有些应用程序完全忽略它,而其他应用程序(如Google Chrome)是像素缩放的(看起来非常丑陋),而其他应用程序则通过使用更大的字体来支持它(这就是我想要的,通常它可以正常工作。只有下面提到的WinRun4J解决方案不能与其一起使用)。
测试过的解决方案
WinRun4J
WinRun4j是一个EXE文件,用于启动Java应用程序。因为该应用程序不会派生出一个新的Java进程,所以Windows认为EXE文件就是该应用程序。因此任务栏没有问题。文件关联也可以工作,因为文件可以简单地与EXE文件相关联。
问题:
- 不支持大字体。应用程序窗口是像素缩放的(像Google Chrome一样)。
- 必须使用两个不同的EXE文件,具体取决于安装的JRE。因此,当64位JRE被安装时,必须使用64位EXE文件来启动应用程序。当32位JRE被安装时,则必须使用另一个EXE文件。这并不用户友好,因为用户不理解为什么在64位操作系统上只安装了32位JRE时,必须使用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或this插件),配置非常容易,并且除了任务栏固定之外,一切都可以直接使用。对于任务栏固定,Java应用程序必须设置appModelUserId,如this question中的答案所述。
此外,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文件的最后一个快捷方式被删除时,任务栏固定将停止工作。