ejecutar exe que está empaquetado dentro de jarra
Pregunta
Estoy ejecutando un exe a través de mi programa java. el camino está codificado en java.
He empaquetado mi exe en el frasco.
Pero estoy atascado ya que tengo el nombre de la ruta codificado en el archivo java. así que no puedo ejecutar mi jarra como un programa independiente.
Cualquier sugerencia para envasar dicho frasco, es decir, tener un exe dentro y ser capaz de ejecutarlo como un programa independiente?
Gracias, Krisp
Solución
Por extraño que parezca, tengo que escribir un código similar esta mañana ... gracias por presionarme para que lo haga :-)
Esto extraerá el .exe
a un archivo local en el disco local. El archivo se eliminará cuando exista el programa Java.
Editar: Whoops, olvidé copiar el archivo ...
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();
}
}
}
}
Otros consejos
El sistema operativo no le importa o no conoce el archivo .jar, por lo que tendrá que descomprimir el archivo .exe
en una ubicación temporal antes de ejecutarlo.
//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();
Mientras que los otros usuarios han respondido la pregunta correctamente, extraiga y ejecute la limpieza. Otro punto a considerar es ir completamente nativo.
Ya estás utilizando un binario nativo para lograr una tarea específica. También puede crear un instalador nativo que instale su aplicación e instalar el binario en la ubicación específica del sistema operativo (Archivos de programa en Win32) y crear accesos directos adecuados.
De esta forma, su aplicación se sentirá más nativa y significa que no necesita escribir ni administrar el código para evitar este hecho. En este momento, el Jar parece una pieza de código multiplataforma (Jar se ejecuta en cualquier lugar, ¿no?), Pero contiene un binario nativo que no se ejecutará en todas partes. Esto se siente como una contradicción.
Para los instaladores, puedo recomendar el Sistema de instalación de Nullsoft (NSIS) ya que tienen excelentes tutoriales y ejemplos de código para aprender.
Utilizar
getClass().getResource(what).openStream()
y cópialo en otro archivo en el disco.
Podrías escribir un programa java simple para iniciar el exe usando Runtime.exec (). A continuación, puede configurar la " Clase principal " atributo de la jarra para ser esa clase lanzador. Los usuarios podrían ejecutar su archivo jar y ejecutaría el exe.