java—运行打包在jar文件中的exe

x8goxv8g  于 2021-07-12  发布在  Java
关注(0)|答案(6)|浏览(376)

我正在通过java程序执行exe。路径是用java硬编码的。
我已经把我的文件打包在jar里了。
但由于我在java文件中硬编码了路径名,所以我无法将jar作为独立程序执行。
有没有关于打包这样的jar的提示,比如说里面有一个exe,并且可以作为一个独立的程序运行?

uurity8g

uurity8g1#

这将提取 .exe 到本地磁盘上的本地文件。当java程序存在时,文件将被删除。

  1. import java.io.Closeable;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.OutputStream;
  8. import java.net.URI;
  9. import java.net.URISyntaxException;
  10. import java.net.URL;
  11. import java.security.CodeSource;
  12. import java.security.ProtectionDomain;
  13. import java.util.zip.ZipEntry;
  14. import java.util.zip.ZipException;
  15. import java.util.zip.ZipFile;
  16. public class Main
  17. {
  18. public static void main(final String[] args)
  19. throws URISyntaxException,
  20. ZipException,
  21. IOException
  22. {
  23. final URI uri;
  24. final URI exe;
  25. uri = getJarURI();
  26. exe = getFile(uri, "Main.class");
  27. System.out.println(exe);
  28. }
  29. private static URI getJarURI()
  30. throws URISyntaxException
  31. {
  32. final ProtectionDomain domain;
  33. final CodeSource source;
  34. final URL url;
  35. final URI uri;
  36. domain = Main.class.getProtectionDomain();
  37. source = domain.getCodeSource();
  38. url = source.getLocation();
  39. uri = url.toURI();
  40. return (uri);
  41. }
  42. private static URI getFile(final URI where,
  43. final String fileName)
  44. throws ZipException,
  45. IOException
  46. {
  47. final File location;
  48. final URI fileURI;
  49. location = new File(where);
  50. // not in a JAR, just return the path on disk
  51. if(location.isDirectory())
  52. {
  53. fileURI = URI.create(where.toString() + fileName);
  54. }
  55. else
  56. {
  57. final ZipFile zipFile;
  58. zipFile = new ZipFile(location);
  59. try
  60. {
  61. fileURI = extract(zipFile, fileName);
  62. }
  63. finally
  64. {
  65. zipFile.close();
  66. }
  67. }
  68. return (fileURI);
  69. }
  70. private static URI extract(final ZipFile zipFile,
  71. final String fileName)
  72. throws IOException
  73. {
  74. final File tempFile;
  75. final ZipEntry entry;
  76. final InputStream zipStream;
  77. OutputStream fileStream;
  78. tempFile = File.createTempFile(fileName, Long.toString(System.currentTimeMillis()));
  79. tempFile.deleteOnExit();
  80. entry = zipFile.getEntry(fileName);
  81. if(entry == null)
  82. {
  83. throw new FileNotFoundException("cannot find file: " + fileName + " in archive: " + zipFile.getName());
  84. }
  85. zipStream = zipFile.getInputStream(entry);
  86. fileStream = null;
  87. try
  88. {
  89. final byte[] buf;
  90. int i;
  91. fileStream = new FileOutputStream(tempFile);
  92. buf = new byte[1024];
  93. i = 0;
  94. while((i = zipStream.read(buf)) != -1)
  95. {
  96. fileStream.write(buf, 0, i);
  97. }
  98. }
  99. finally
  100. {
  101. close(zipStream);
  102. close(fileStream);
  103. }
  104. return (tempFile.toURI());
  105. }
  106. private static void close(final Closeable stream)
  107. {
  108. if(stream != null)
  109. {
  110. try
  111. {
  112. stream.close();
  113. }
  114. catch(final IOException ex)
  115. {
  116. ex.printStackTrace();
  117. }
  118. }
  119. }
  120. }
展开查看全部
iovurdzv

iovurdzv2#

操作系统不关心或不知道.jar文件,因此您必须解包 .exe 在执行之前,将文件保存到某个临时位置。

v6ylcynt

v6ylcynt3#

  1. //gets program.exe from inside the JAR file as an input stream
  2. InputStream is = getClass().getResource("program.exe").openStream();
  3. //sets the output stream to a system folder
  4. OutputStream os = new FileOutputStream("program.exe");
  5. //2048 here is just my preference
  6. byte[] b = new byte[2048];
  7. int length;
  8. while ((length = is.read(b)) != -1) {
  9. os.write(b, 0, length);
  10. }
  11. is.close();
  12. os.close();
j8ag8udp

j8ag8udp4#

当其他用户正确回答问题时,提取并运行cleanup。另一个需要考虑的问题是完全本土化。
您已经在使用本机二进制文件来实现特定任务。为什么不创建一个本机安装程序来安装应用程序,并将二进制文件安装到操作系统特定的位置(win32上的程序文件)并创建合适的快捷方式。
这样,您的应用程序将感觉更加原生,意味着您不需要编写或管理代码来绕过这个事实。目前,jar看起来像是一段跨平台的代码(jar可以在任何地方运行吗?),但它打包了一个本机二进制文件,不会在任何地方运行。这感觉很矛盾。
对于安装人员,我可以推荐nullsoft安装系统(nsis),因为他们有许多优秀的教程和代码示例可供学习。

6psbrbz9

6psbrbz95#

使用

  1. getClass().getResource(what).openStream()

并复制到磁盘中的另一个文件。

bq8i3lrv

bq8i3lrv6#

您可以编写一个简单的java程序来使用runtime.exec()启动exe。然后可以将jar的“main class”属性设置为该启动器类。然后用户可以运行jar,它将运行exe。

相关问题