изменение рабочего каталога команды с Java - PullRequest
17 голосов
/ 25 июля 2011

Мне нужно выполнить файл .exe из функции в одном из пакетов, которые у меня есть в моем проекте Java.теперь рабочий каталог является корневым каталогом проекта для Java, но файл .exe в подкаталогах моего проекта.Вот как организован проект:

ROOT_DIR
|.......->com
|         |......->somepackage
|                 |.........->callerClass.java
|
|.......->resource
         |........->external.exe

Изначально я пытался запустить файл .exe напрямую через:

String command = "resources\\external.exe  -i input -o putpot";
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command);

, но проблема в том, что внешнему .exe требуется доступ к некоторым файламв своем собственном каталоге и продолжает думать, корневой каталог является его каталогом.Я даже пытался использовать файл .bat для решения проблемы, но возникает та же проблема:

Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "resources\\helper.bat"});

, и файл .bat находится в том же каталоге, что и файл .exe, но возникает та же проблема.Вот содержимое файла .bat:

@echo off
echo starting process...

external.exe -i input -o output

pause

, даже если я переместлю файл .bat в корневой каталог и исправлю его содержимое, проблема не исчезнет.плз плз помогите

Ответы [ 3 ]

22 голосов
/ 25 июля 2011

Для реализации этого вы можете использовать класс ProcessBuilder, вот как это будет выглядеть:

File pathToExecutable = new File( "resources/external.exe" );
ProcessBuilder builder = new ProcessBuilder( pathToExecutable.getAbsolutePath(), "-i", "input", "-o", "output");
builder.directory( new File( "resources" ).getAbsoluteFile() ); // this is where you set the root folder for the executable to run with
builder.redirectErrorStream(true);
Process process =  builder.start();

Scanner s = new Scanner(process.getInputStream());
StringBuilder text = new StringBuilder();
while (s.hasNextLine()) {
  text.append(s.nextLine());
  text.append("\n");
}
s.close();

int result = process.waitFor();

System.out.printf( "Process exited with result %d and output %s%n", result, text );

Это довольно много кода, но он дает вам еще больший контроль над тем, как будет выполняться процесс.

16 голосов
/ 25 июля 2011

Используйте эту форму метода exec , чтобы указать рабочий каталог

public Process exec(String[] cmdarray,
                    String[] envp,
                    File dir)
             throws IOException

Рабочий каталог - третий аргумент.Вы можете передать null для envp, если вам не нужно устанавливать какую-либо специальную среду.

Существует также этот удобный метод :

public Process exec(String command,
                    String[] envp,
                    File dir)
             throws IOException

.... где вы указываете команду в одной строке (она просто превращается в массив для вас; подробности см. в документации).

0 голосов
/ 16 февраля 2017

Я столкнулся с той же проблемой в своем проекте, я попробовал это решение о ProcessBuilder.directory(myDir), метод exec из Runtime и все мои лотки не удалось ..Это заставляет меня понять, что Runtime имеет ограниченные привилегии только для рабочего каталога и его подкаталогов.Так что мое решение некрасиво, но работает очень хорошо.Я создаю временный файл .bat в «runtime» в рабочем каталоге.Этот файл включает две строки команд:1. Перейдите в нужный каталог (команда cd).2. Выполните команду при необходимости.Я вызываю exec от Runtime с моим временно .bat файлом в качестве команды.Это работа для меня очень хорошо!

...