문제

나는 Java 프로그램을 통해 EXE를 실행하고 있습니다. 경로는 Java로 하드 코딩됩니다.

나는 항아리에 내 exe를 포장했다.

그러나 Java 파일에 경로 이름이 하드 코드 된 상태에서 붙어 있습니다. 따라서 내 항아리를 독립형 프로그램으로 실행할 수 없습니다.

그러한 항아리를 포장하는 힌트, 즉 내부에 exe가 있고 독립형 프로그램으로 실행할 수 있습니까?

감사합니다, Krisp

도움이 되었습니까?

해결책

이상하게도 오늘 아침에 비슷한 코드를 써야합니다 ... 그 일을하도록 강요 해 주셔서 감사합니다 :-)

이것은 추출합니다 .exe 로컬 디스크의 로컬 파일에. Java 프로그램이 존재하면 파일이 삭제됩니다.

편집 : Whoops, 실제로 파일을 복사하는 것을 잊었습니다 ...

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

다른 팁

The operating system doesn't care or know about .jar file, so you'll have to unpack the .exe file to some temporary location before you execute it.

//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();

Whilst the other users have answered the question correctly, extract and run then cleanup. Another point to consider is going fully native.

You are already using a native binary to achieve a specific task. Why not also create a native installer which will install your application, and install the binary to the OS specific location (Program Files on Win32) and create suitable shortcuts.

This way your application will feel more native and means you don't need to write or manage code to get around this fact. At the moment the Jar looks like a cross platform piece of code (Jar runs anywhere right?) but packs a native binary which will not run everywhere. This feels like a contradiction.

For installers I can recommend Nullsoft Installation System (NSIS) as they have many excellent tutorials and code samples to learn from.

Use

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

and copy to another file in the disk.

You could write a simple java program to launch the exe using Runtime.exec(). You could then set the "Main-Class" attribute of the jar to be that launcher class. Users could then run your jar and it would run the exe.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top