Pytanie zmiana katalogu roboczego polecenia z java


Muszę wykonać plik .exe z funkcji w jednym z pakietów, które mam w moim projekcie java. teraz katalog roboczy jest katalogiem głównym projektu dla java, ale plik .exe w podkatalogach mojego projektu. Oto jak zorganizowany jest projekt:

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

Początkowo próbowałem uruchomić plik .exe bezpośrednio przez:

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

ale problemem jest zewnętrzny .exe musi uzyskać dostęp do niektórych plików w swoim własnym katalogu i wciąż myśli, że katalog główny jest jego katalogiem. Próbowałem nawet użyć pliku .bat, aby rozwiązać problem, ale ten sam problem rośnie:

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

a plik .bat znajduje się w tym samym katalogu, co plik .exe, ale występuje ten sam problem. tutaj jest zawartość pliku .bat:

@echo off
echo starting process...

external.exe -i input -o output

pause

nawet jeśli przeniesię plik .bat do katalogu głównego i naprawię jego zawartość, problem nie zniknie. plz plz plz help


15
2017-07-25 03:26


pochodzenie




Odpowiedzi:


Aby to zaimplementować, możesz użyć klasy ProcessBuilder, oto jak to będzie wyglądało:

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

To całkiem spora ilość kodu, ale daje jeszcze większą kontrolę nad procesem.


20
2017-07-25 03:45



wygląda na rozsądną, ale nie mogę uwierzyć, że nie ma prostszej metody osiągnięcia zamierzonego rezultatu - prusswan
Absolutnie piękna!!! dziękuje bardzo :) - user804723


Posługiwać się ta forma exec metoda aby określić katalog roboczy

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

Katalog roboczy jest trzecim argumentem. Możesz przejść null dla envp jeśli nie musisz ustawiać żadnego specjalnego środowiska.

Jest także ta wygodna metoda:

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

... gdzie określasz polecenie w jednym ciągu (po prostu zmienia się w tablicę dla ciebie, zobacz dokumentację dla szczegółów).


14
2017-07-25 03:39





Mam ten sam problem w moim projekcie, próbowałem tego rozwiązania ProcessBuilder.directory(myDir) i metoda exec z Runtime i wszystkie moje tace zawiodły ...
To sprawia, że ​​rozumiem, że Runtime mają ograniczone uprawnienia tylko do katalogu roboczego i podkatalogów tego katalogu.

Moje rozwiązanie jest brzydkie, ale działa bardzo dobrze.
Tworzę tymczasowy plik .bat w "uruchomieniu" w katalogu roboczym.
Ten plik zawierał dwa wiersze poleceń:
1. Przejdź do żądanego katalogu (polecenie cd).
2. Wykonaj polecenie w razie potrzeby.
Dzwonię do exec z Runtime  z moim tymczasowym plikiem .bat jako poleceniem.
To dla mnie bardzo dobrze!


0
2018-02-16 18:01