我正在通过java程序执行exe。路径是用java硬编码的。我已经把我的文件打包在jar里了。但由于我在java文件中硬编码了路径名,所以我无法将jar作为独立程序执行。有没有关于打包这样的jar的提示,比如说里面有一个exe,并且可以作为一个独立的程序运行?
uurity8g1#
这将提取 .exe 到本地磁盘上的本地文件。当java程序存在时,文件将被删除。
.exe
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(); } } }}
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;
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,
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,
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;
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);
close(zipStream);
close(fileStream);
return (tempFile.toURI());
private static void close(final Closeable stream)
if(stream != null)
stream.close();
catch(final IOException ex)
ex.printStackTrace();
iovurdzv2#
操作系统不关心或不知道.jar文件,因此您必须解包 .exe 在执行之前,将文件保存到某个临时位置。
v6ylcynt3#
//gets program.exe from inside the JAR file as an input streamInputStream is = getClass().getResource("program.exe").openStream();//sets the output stream to a system folderOutputStream os = new FileOutputStream("program.exe");//2048 here is just my preferencebyte[] b = new byte[2048];int length;while ((length = is.read(b)) != -1) { os.write(b, 0, length);}is.close();os.close();
//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();
j8ag8udp4#
当其他用户正确回答问题时,提取并运行cleanup。另一个需要考虑的问题是完全本土化。您已经在使用本机二进制文件来实现特定任务。为什么不创建一个本机安装程序来安装应用程序,并将二进制文件安装到操作系统特定的位置(win32上的程序文件)并创建合适的快捷方式。这样,您的应用程序将感觉更加原生,意味着您不需要编写或管理代码来绕过这个事实。目前,jar看起来像是一段跨平台的代码(jar可以在任何地方运行吗?),但它打包了一个本机二进制文件,不会在任何地方运行。这感觉很矛盾。对于安装人员,我可以推荐nullsoft安装系统(nsis),因为他们有许多优秀的教程和代码示例可供学习。
6psbrbz95#
使用
getClass().getResource(what).openStream()
并复制到磁盘中的另一个文件。
bq8i3lrv6#
您可以编写一个简单的java程序来使用runtime.exec()启动exe。然后可以将jar的“main class”属性设置为该启动器类。然后用户可以运行jar,它将运行exe。
6条答案
按热度按时间uurity8g1#
这将提取
.exe
到本地磁盘上的本地文件。当java程序存在时,文件将被删除。iovurdzv2#
操作系统不关心或不知道.jar文件,因此您必须解包
.exe
在执行之前,将文件保存到某个临时位置。v6ylcynt3#
j8ag8udp4#
当其他用户正确回答问题时,提取并运行cleanup。另一个需要考虑的问题是完全本土化。
您已经在使用本机二进制文件来实现特定任务。为什么不创建一个本机安装程序来安装应用程序,并将二进制文件安装到操作系统特定的位置(win32上的程序文件)并创建合适的快捷方式。
这样,您的应用程序将感觉更加原生,意味着您不需要编写或管理代码来绕过这个事实。目前,jar看起来像是一段跨平台的代码(jar可以在任何地方运行吗?),但它打包了一个本机二进制文件,不会在任何地方运行。这感觉很矛盾。
对于安装人员,我可以推荐nullsoft安装系统(nsis),因为他们有许多优秀的教程和代码示例可供学习。
6psbrbz95#
使用
并复制到磁盘中的另一个文件。
bq8i3lrv6#
您可以编写一个简单的java程序来使用runtime.exec()启动exe。然后可以将jar的“main class”属性设置为该启动器类。然后用户可以运行jar,它将运行exe。