Правильный способ выполнения исполняемого файла (.exe) в разных ситуациях - PullRequest
4 голосов
/ 31 октября 2011

Такая проблема уже давно меня беспокоит, поэтому мне было любопытно, как вы подходите к решению следующей ситуации:

Представьте, что у меня есть два разных проекта Eclipse в одной рабочей области под названием ProjectA и ProjectB. ProjectB содержит в своем корневом каталоге .exe-файл, который вызывается из ProjectA следующим образом:

Process p = Runtime.getRuntime().exec( "../ProjectB/ProjectB.exe" );

Проблема в том, что после развертывания структура немного меняется: ProjectA теперь является .jar. Рядом с этим jar теперь находится папка с ProjectB, которая содержит ProjectB с его файлами .exe, .jars и так далее. Теперь правильный вызов должен выглядеть следующим образом:

Process p = Runtime.getRuntime().exec( "ProjectB/ProjectB.exe" );

Поскольку мне нужно, чтобы эти структуры оставались такими, как есть, и я не хочу, чтобы в моем приложении для каждого случая было два разных вызова .exec, я попробовал несколько способов обойти эту ситуацию:

1) Добавление ProjectB в качестве ClassFolder в ProjectA и предоставление возможности ContextClassLoader выяснить, где найти ProjectB.exe следующим образом:

URL url= Thread.currentThread().getContextClassLoader().getResource( "ProjectB.exe" );
file = new File( url.toURI() );
Process p = Runtime.getRuntime().exec( file.getAbsolutePath() );

Это решение прекрасно работало, пока я не попытался развернуть свое приложение на сетевом диске.

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: URI has an authority component
    at java.io.File.<init>(Unknown Source)

2) Поскольку мне не разрешено создавать сетевой диск для каждого клиента, я попытался обойти эту проблему и сделал следующее:

URL url= Thread.currentThread().getContextClassLoader().getResource( "ProjectB.exe" );
File file = new File( url.getFile() );
Process p = Runtime.getRuntime().exec( file.getAbsolutePath() );

Это казалось многообещающим, но, к сожалению, до тех пор, пока мой путь оставался без черточек (""), поскольку этот appraoch, казалось, преобразовывал каждую черточку в "% 20", что на самом деле не похоже, что runtimeexecutor не нравится. Конечно, после этого я мог бы заменить каждый "% 20" на "", но мне это кажется немного хакерским.

Другое требование состоит в том, что оба приложения должны работать в другой JVM, поэтому я называю .exe-файл методом Runtimeexecution. Итак, мой последний вопрос: есть ли способ очистить вызовы ProjectB без каких-либо обходных путей?

1 Ответ

1 голос
/ 31 октября 2011

Чистый способ - определить путь поиска (несколько экземпляров File, которые указывают на другой каталог). Добавьте имя exe-файла к каждому пути и проверьте, существует ли полученный File, и используйте этот путь для его выполнения.

Исключение составляет уровень безопасности Windows: он не позволяет запускать неизвестные исполняемые файлы по сетевому пути. Обратитесь к системному администратору за решением.

Обратите внимание, что вы не всегда можете загрузить exe-файлы из пути к классам. Например, если они находятся внутри JAR, это не сработает. Средство запуска Windows не знает, как обрабатывать файлы JAR. Решение здесь состоит в том, чтобы распаковать ресурс во временный файл и запустить его оттуда.

...