2009-03-01 14 views
18

Wykonuję exe poprzez mój program java. ścieżka jest oznaczona na stałe w Javie.uruchom exe, który jest zapakowany wewnątrz słoiczka

Mam pakowane mój exe w słoiku.

Ale utknąłem, ponieważ nazwa ścieżki została zakodowana na stałe w pliku Java. , więc nie jestem w stanie wykonać mojego słoika jako samodzielnego programu.

Jakieś wskazówki dotyczące pakowania takiego słoika, np. Czy masz exe wewnątrz i czy jesteś w stanie uruchomić go jako samodzielny program?

Dzięki, Krisp

Odpowiedz

30

dziwo muszę napisać podobny kod rano ... dzięki za popychanie mnie dostać się robi :-)

To wyodrębnić .exe do lokalnego pliku na dysku lokalnym. Plik zostanie usunięty, gdy istnieje program Java.

Edit: Ups, zapomniałem faktycznie skopiować plik ...

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

Nie zapomnij ustawić flagi wykonywalnej, w przeciwnym razie twój kod działa tylko w systemie Windows. – akuhn

+2

+1 do utworzenia pliku tymczasowego i oznaczenia go jako usunięcia przy wyjściu. – gencoreoperative

+0

Wiem, że to stare pytanie, ale próbuję użyć kodu podobnego do tego z Windows 7, ale nie mogę wykonać '.exe's w katalogu tymczasowym. Byłbym wdzięczny, gdybyś mógł sprawdzić moje pytanie: http://stackoverflow.com/questions/18559835/access-denied-when-trying-to-execute-a-exe-in-appdata – Andy

11

System operacyjny nie obchodzi mnie czy wiem o .jar, więc trzeba rozpakować plik .exe do jakiejś tymczasowej lokalizacji przed wykonaniem go.

+0

skopiowałem plik z zasobami do katalogu głównego projektu przy użyciu metody opisanej D.Snap i jestem teraz nawiązując do pliku tak: „pliku file = new File (” your.exe”); ". Możesz więc otworzyć plik do zapisania w katalogu głównym z katalogu zasobów (jeśli korzystasz z projektu): "InputStream is = getClass(). GetResource (" your.exe "). OpenStream();" – hipokito

-5

Można napisać prosty program java, aby uruchomić plik exe za pomocą Runtime.exec(). Następnie możesz ustawić atrybut "Klasy Głównej" dla słoika, który będzie tą klasą programu uruchamiającego. Użytkownicy mogliby wtedy uruchomić twój słoik i uruchomiłoby go exe.

+0

W tym przypadku będę wymagać twardego kodu ścieżki exe w kodzie java. Chcę, żeby była przenośna. – krisp

+0

@Krisp. Nie prawda.Możesz użyć Class/ClassLoader.getResource(), aby znaleźć względną ścieżkę wewnątrz słoika – Kevin

+0

dzięki ... to wydaje się pewne nadzieje .. wypróbuje to i pozwoli ci wiedzieć. – krisp

3

Podczas gdy inni użytkownicy poprawnie odpowiedział na pytanie, ekstrakt i uruchomić następnie oczyszczanie. Kolejny punkt do rozważenia jest całkowicie rodzimy.

Już używasz natywnego pliku binarnego do osiągnięcia określonego zadania. Dlaczego nie utworzyć natywnego instalatora, który zainstaluje aplikację i zainstaluje plik binarny w określonej lokalizacji systemu operacyjnego (Program Files na Win32) i utworzy odpowiednie skróty.

W ten sposób aplikacja będzie czuć się bardziej natywna i oznacza, że ​​nie trzeba pisać ani zarządzać kodem, aby ominąć ten fakt. W tej chwili Jar wygląda jak wieloplatformowy fragment kodu (Jar biegnie gdziekolwiek w prawo?), Ale pakuje natywną wersję binarną, która nie będzie działać wszędzie. To wydaje się sprzecznością.

Dla instalatorów mogę polecić system instalacyjny Nullsoft (NSIS), ponieważ ma wiele doskonałych samouczków i próbek kodu do nauki.

2

Zastosowanie

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

i skopiować do innego pliku na dysku.

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(); 
Powiązane problemy