Java 运行打包在 jar 文件中的 exe
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/600146/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Run exe which is packaged inside jar file
提问by krisp
I am executing an exe through my java program. The path is hardcoded in Java.
我正在通过我的 java 程序执行一个 exe。路径是用 Java 硬编码的。
I have packaged my the exe in the jar.
我已经将我的 exe 打包在 jar 中。
But am stuck as I have the path name hardcoded in the Java file, so I am not able to execute my jar as a stand alone program.
但是我卡住了,因为我在 Java 文件中硬编码了路径名,所以我无法将我的 jar 作为独立程序执行。
Any hints for packaging such jar i.e having an exe inside and able to run it as a stand alone program?
打包此类 jar 的任何提示,即内部有一个 exe 并能够将其作为独立程序运行?
采纳答案by TofuBeer
This will extract the .exe
to a local file on the local disk. The file will be deleted when the Java program exists.
这会将 解压缩.exe
到本地磁盘上的本地文件。当 Java 程序存在时,该文件将被删除。
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
public class Main
{
public static void main(final String[] args)
throws URISyntaxException,
ZipException,
IOException
{
final URI uri;
final URI exe;
uri = getJarURI();
exe = getFile(uri, "Main.class");
System.out.println(exe);
}
private static URI getJarURI()
throws URISyntaxException
{
final ProtectionDomain domain;
final CodeSource source;
final URL url;
final URI uri;
domain = Main.class.getProtectionDomain();
source = domain.getCodeSource();
url = source.getLocation();
uri = url.toURI();
return (uri);
}
private static URI getFile(final URI where,
final String fileName)
throws ZipException,
IOException
{
final File location;
final URI fileURI;
location = new File(where);
// not in a JAR, just return the path on disk
if(location.isDirectory())
{
fileURI = URI.create(where.toString() + fileName);
}
else
{
final ZipFile zipFile;
zipFile = new ZipFile(location);
try
{
fileURI = extract(zipFile, fileName);
}
finally
{
zipFile.close();
}
}
return (fileURI);
}
private static URI extract(final ZipFile zipFile,
final String fileName)
throws IOException
{
final File tempFile;
final ZipEntry entry;
final InputStream zipStream;
OutputStream fileStream;
tempFile = File.createTempFile(fileName, Long.toString(System.currentTimeMillis()));
tempFile.deleteOnExit();
entry = zipFile.getEntry(fileName);
if(entry == null)
{
throw new FileNotFoundException("cannot find file: " + fileName + " in archive: " + zipFile.getName());
}
zipStream = zipFile.getInputStream(entry);
fileStream = null;
try
{
final byte[] buf;
int i;
fileStream = new FileOutputStream(tempFile);
buf = new byte[1024];
i = 0;
while((i = zipStream.read(buf)) != -1)
{
fileStream.write(buf, 0, i);
}
}
finally
{
close(zipStream);
close(fileStream);
}
return (tempFile.toURI());
}
private static void close(final Closeable stream)
{
if(stream != null)
{
try
{
stream.close();
}
catch(final IOException ex)
{
ex.printStackTrace();
}
}
}
}
回答by Joachim Sauer
The operating system doesn't care or know about .jar file, so you'll have to unpack the .exe
file to some temporary location before you execute it.
操作系统不关心或知道 .jar 文件,因此您必须.exe
在执行之前将该文件解压缩到某个临时位置。
回答by Kevin
You could write a simple java program to launch the exe using Runtime.exec(). You could then set the "Main-Class" attribute of the jar to be that launcher class. Users could then run your jar and it would run the exe.
您可以编写一个简单的 java 程序来使用 Runtime.exec() 启动 exe。然后,您可以将 jar 的“Main-Class”属性设置为该启动器类。然后用户可以运行您的 jar,它会运行 exe。
回答by gencoreoperative
Whilst the other users have answered the question correctly, extract and run then cleanup. Another point to consider is going fully native.
在其他用户正确回答问题的同时,提取并运行然后清理。要考虑的另一点是完全本地化。
You are already using a native binary to achieve a specific task. Why not also create a native installer which will install your application, and install the binary to the OS specific location (Program Files on Win32) and create suitable shortcuts.
您已经在使用本机二进制文件来完成特定任务。为什么不创建一个本地安装程序来安装您的应用程序,并将二进制文件安装到操作系统特定位置(Win32 上的程序文件)并创建合适的快捷方式。
This way your application will feel more native and means you don't need to write or manage code to get around this fact. At the moment the Jar looks like a cross platform piece of code (Jar runs anywhere right?) but packs a native binary which will not run everywhere. This feels like a contradiction.
通过这种方式,您的应用程序会感觉更原生,这意味着您无需编写或管理代码来解决这个问题。目前,Jar 看起来像一段跨平台的代码(Jar 可以在任何地方运行,对吗?)但打包了一个不会在任何地方运行的本机二进制文件。这感觉很矛盾。
For installers I can recommend Nullsoft Installation System (NSIS) as they have many excellent tutorials and code samples to learn from.
对于安装人员,我可以推荐 Nullsoft Installation System (NSIS),因为他们有许多优秀的教程和代码示例可供学习。
回答by Mid Bifroid
Use
用
getClass().getResource(what).openStream()
and copy to another file in the disk.
并复制到磁盘中的另一个文件。
回答by D.Snap
//gets program.exe from inside the JAR file as an input stream
InputStream is = getClass().getResource("program.exe").openStream();
//sets the output stream to a system folder
OutputStream os = new FileOutputStream("program.exe");
//2048 here is just my preference
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();