exe4j打包的javafx程序执行类路径下的bat文件的思路分享
写在前面
最近用javafx开发了一个功能:
-
界面会收集用户输入的一些参数,这些参数是文件auto_run_wukong_v5.bat的入参
-
文件auto_run_wukong_v5.bat是一个bat脚本,会执行一些功能,文件auto_run_wukong_v5.bat在工程的resources/batscript目录下
-
界面收集完参数之后,和auto_run_wukong_v5.bat拼接起来执行
拼接起来的命令类似下面的样子:
cmd.exe /c call C:\Users\fenglv\AppData\Local\Temp\test6886265563528579288.bat 0*******39 520808 1000 50 C 0.02 0.3 0.6
来看下部分关键代码
StringBuilder callWukongV5 = new StringBuilder("cmd.exe /c call ");
File file = null;
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("batscript/auto_run_wukong_v5.bat");
if (inputStream != null) {
// 创建临时文件
try {
file = File.createTempFile("test", ".bat");
file.deleteOnExit();
try (OutputStream outputStream = new FileOutputStream(file)) {
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
outputStream.flush();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
callWukongV5.append(file);
理一下这段代码的思路:
-
通过类加载先把类路径下的bat文件读出来
-
根据bat文件的内容再生成一个临时的bat文件
-
最后再执行这个临时的bat文件来变相地达到在exe文件中可以执行类路径下的bat文件,真的感觉好繁琐
目前我能想到的就是这方法,在网上查了下好像也就这方法可以实现,给出的原因如下:
直接在 Java 应用程序中执行类路径下的 .bat
文件(不复制到临时文件)通常是不可能的,因为类路径下的资源在运行时是打包在 JAR 文件中的,而不是作为可执行文件存在。Java 运行时环境不允许直接从 JAR 文件中执行文件,因为这涉及到安全风险。
所以:
在 Exe4j 打包的应用程序中,通常的做法是将 .bat
文件作为资源包含在 JAR 中,然后在运行时将其生成到临时目录下并执行。这样做可以确保应用程序的可移植性和封装性。
遇到的坑点
千万要注意类加载器加装文件时的路径问题:
//下面的写法在idea工程和打包成的exe文件中运行都没问题
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("batscript/auto_run_wukong_v5.bat");
//但是如果这样写,在idea工程运行没问题,但是在打包成的exe文件中运行有问题,找不到文件batscript/auto_run_wukong_v5.bat,代码运行之后inputStream为空
// 这个\\路径看来也是一个坑
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("batscript\\auto_run_wukong_v5.bat");
也可以有别的方式来变相实现
比如把文件batscript/auto_run_wukong_v5.bat与exe4j打包成的exe文件放在同一目录,这样在执行cmd.exe /c call batscript/auto_run_wukong_v5.bat
时也是可以找到文件batscript/auto_run_wukong_v5.bat的,它会在运行的exe文件的当前目录去查找。
但是这种方法不好,每当batscript目录下新增bat脚本之后,还需要把新增的bat脚本发给软件使用者,因为如果软件使用者本地无这个bat脚本那就无法正常运行程序。
编写日期
-
2024-9-4
-
2024-9-6