2009-03-01 31 views
18

Tôi đang thực hiện một exe thông qua chương trình java của tôi. đường dẫn được mã hóa cứng trong java.chạy exe được đóng gói bên trong jar

Tôi đã đóng gói exe của mình trong bình.

Nhưng bị kẹt khi tôi có tên đường dẫn được mã hóa cứng trong tệp java. vì vậy tôi không thể thực hiện bình của tôi như một chương trình độc lập.

Bất kỳ gợi ý nào về việc đóng gói bình như vậy, tức là có một exe bên trong và có thể chạy nó như một chương trình độc lập?

Cảm ơn, Krisp

Trả lời

30

Lạ lùng thay tôi phải viết mã tương tự như sáng nay ... thanks for đẩy tôi để nhận được rằng thực hiện :-)

này sẽ trích xuất các .exe vào một tập tin địa phương trên đĩa địa phương. Tệp sẽ bị xóa khi chương trình Java tồn tại.

Chỉnh sửa: Rất tiếc, quên thực sự sao chép các tập tin ...

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(); 
      } 
     } 
    } 
} 
+7

Đừng quên đặt cờ thực thi, nếu không mã của bạn chỉ hoạt động trên Windows. – akuhn

+2

+1 để tạo tệp tạm thời và đánh dấu nó xóa khi thoát. – gencoreoperative

+0

Tôi biết đây là một câu hỏi cũ, nhưng tôi đang cố gắng sử dụng mã tương tự như vậy với Windows 7, nhưng tôi không thể thực thi '.exe' trong thư mục tạm thời. Sẽ đánh giá cao nếu bạn có thể xem câu hỏi của tôi: http://stackoverflow.com/questions/18559835/access-denied-when-trying-to-execute-a-exe-in-appdata – Andy

11

Hệ điều hành không quan tâm hoặc biết về tập tin .jar, vì vậy bạn sẽ phải giải nén các tập tin .exe đối với một số vị trí tạm thời trước khi bạn thực hiện nó.

+0

tôi sao chép các tập tin từ các nguồn lực vào thư mục gốc của dự án sử dụng phương pháp mô tả và D.Snap Tôi bây giờ đề cập đến các tập tin như vậy: "File file = new File (" your.exe"); ". Vì vậy, bạn có thể mở tệp để ghi vào thư mục gốc từ thư mục tài nguyên (nếu bạn đang sử dụng dự án maven) như sau: "InputStream is = getClass(). GetResource (" your.exe "). OpenStream();" – hipokito

-5

Bạn có thể viết một chương trình java đơn giản để khởi chạy exe bằng cách sử dụng Runtime.exec(). Sau đó bạn có thể thiết lập thuộc tính "Main-Class" của jar là lớp launcher. Người dùng có thể chạy jar của bạn và nó sẽ chạy exe.

+0

Trong trường hợp này tôi sẽ yêu cầu mã cứng đường dẫn exe trong mã java. Tôi muốn làm cho nó di động. – krisp

+0

@Krisp. Không đúng.Bạn có thể sử dụng Class/ClassLoader.getResource() để tìm một đường dẫn tương đối trong jar – Kevin

+0

cảm ơn .. điều này có vẻ là một số hy vọng..sẽ thử điều này và cho bạn biết. – krisp

3

Trong khi những người dùng khác đã trả lời câu hỏi một cách chính xác, giải nén và chạy sau đó dọn dẹp. Một điểm khác cần xem xét là hoàn toàn có nguồn gốc.

Bạn đang sử dụng nhị phân gốc để đạt được một tác vụ cụ thể. Tại sao không cũng tạo một trình cài đặt gốc sẽ cài đặt ứng dụng của bạn và cài đặt nhị phân vào vị trí cụ thể của hệ điều hành (Program Files trên Win32) và tạo các phím tắt phù hợp.

Bằng cách này, ứng dụng của bạn sẽ cảm thấy bản địa hơn và có nghĩa là bạn không cần phải viết hoặc quản lý mã để tránh sự thật này. Tại thời điểm này, Jar trông giống như một đoạn mã chéo (Jar chạy ở bất kỳ đâu?) Nhưng gói một tệp nhị phân gốc sẽ không chạy ở mọi nơi. Điều này cảm thấy như một mâu thuẫn.

Đối với trình cài đặt, tôi có thể đề xuất Hệ thống cài đặt Nullsoft (NSIS) vì chúng có nhiều hướng dẫn và mẫu mã tuyệt vời để học hỏi.

2

Sử dụng

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

và sao chép vào một tập tin trong đĩa.

3
//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(); 
Các vấn đề liên quan