我的问题是,我做了某种启动器并编写了一个方法,如果你点击“播放”按钮就会被调用。
private void PlayButtonActionPerformed(java.awt.event.ActionEvent evt) {
try
{
new ProcessBuilder("src/calc.exe").start();
}
catch (IOException ex)
{
Logger.getLogger(Launcher.class.getName()).log(Level.SEVERE, null, ex);
}
}
正在执行的文件只是Windows和Windows计算器的副本 在我的项目的src文件夹中。 (路径是“src / calc.exe”)
一切正常,因为我没有将我的netbeans项目文件编译成JAR文件。
如果我运行JAR文件并单击播放按钮 - 没有任何反应。
我真的希望你能告诉我如何解决这个问题。
(P.S。:calc.exe并不总是要运行的程序的名称。文件名由.ini确定。 calc.exe仅用于测试程序。)
答案 0 :(得分:2)
首先,一些背景:
JAR
文件是一个存档,一个包(压缩与否),包含Java字节码和可以从JVM内部使用的其他资源。EXE
文件是可执行的二进制文件,只能由Windows / MS-DOS系列操作系统理解。当您运行程序而不将其打包到JAR文件中时,可以从操作系统访问所有资源(类文件和可执行文件)。 Windows将启动JVM,并从内部通过ProcessBuilder
指示操作系统调用可在相对于执行执行指令的类的路径中访问的可执行文件。直到那里,一切都很好,正如你所说,它有效。
但是,当您将Java类和可执行文件打包到JAR中并调用JAR时,操作系统将无法再访问其内容。发生的事情是操作系统将启动JVM,它将处理JAR文件以查找可执行类(您调用ProcessBuilder
的类)。从该类文件中,您现在指示操作系统启动可执行文件,该可执行文件位于相对于JAR文件的路径中,而不是相对于执行调用指令的类文件。由于EXE在JAR文件中而不是相对于它,因此执行失败,因为它无法找到可执行文件。
这就是这种方式,因为操作系统不会在JAR文件中查找特定文件,对于操作系统而言,JAR文件只是一个文件,而不是文件夹,因此它将忽略其内容。
因此,结论是,由于您正在调用操作系统以在另一个文件中执行特定操作,因此只需将该文件放在JAR之外并放在该JAR的相对路径中。
如果由于某种原因你坚持在EXAR中包装你的EXE,那么你需要在JAR之外提取它,然后再调用ProcessBuilder
到一个临时文件夹并使用那条新路径调用ProcessBuilder
答案 1 :(得分:1)
这是一个敏感话题。
无论是谁评论JAR都无法做到这一点都是错误的。相反,除非作者通过Oracle签名和验证,否则applet没有这样的权限。
你说除非你把它放在JAR中,否则一切正常。这可能是因为您的URI相对于Windows文件系统。
无论参考文件周围的包装如何,通常获取文件的方法是执行以下操作:
MainClass.class.getResourceAsStream(file);
静态getResourceAsStream将解析可用的相对路径和绝对路径,如果你把“src / calc.exe”放在这里,它应该可以工作。
另一个建议是打开流程。如果您将程序作为单个线程,Java程序将挂起,直到外部进程消失并清理完毕。