Java 애플리케이션에서 배치 파일을 어떻게 실행합니까?


107

Java 애플리케이션에서 " scons -Q implicit-deps-changed build\file_load_type export\file_load_type" 를 호출하는 배치 파일을 실행하려고합니다.

배치 파일을 실행할 수없는 것 같습니다. 나는 아이디어가 없습니다.

이것이 내가 Java에있는 것입니다.

Runtime.
   getRuntime().
   exec("build.bat", null, new File("."));

이전에는 실행하고 싶은 Python Sconscript 파일이 있었지만 작동하지 않았기 때문에 배치 파일을 통해 스크립트를 호출하기로 결정했지만 그 방법은 아직 성공하지 못했습니다.

답변:


172

배치 파일은 실행 파일이 아닙니다. 이를 실행하려면 응용 프로그램 (예 : cmd)이 필요합니다.

UNIX에서 스크립트 파일은 파일을 실행하는 프로그램을 지정하기 위해 파일 시작 부분에 shebang (#!)이 있습니다. Windows에서 더블 클릭은 Windows 탐색기에서 수행됩니다. CreateProcess그것에 대해 아무것도 모릅니다.

Runtime.
   getRuntime().
   exec("cmd /c start \"\" build.bat");

참고 : start \"\"명령을 사용하면 빈 제목으로 별도의 명령 창이 열리고 배치 파일의 모든 출력이 여기에 표시됩니다. 또한`cmd / c build.bat "와 함께 작동해야합니다.이 경우 원하는 경우 Java의 하위 프로세스에서 출력을 읽을 수 있습니다.


저에게는 Windows가 "build.bat"를 찾을 수 없다고 말합니다. 이 파일을 어디에 두어야합니까? 아니면 내가 어떻게 길을 알려야할까요. 어떤 제안?
nanospeck

1
명령의 배열이 있고 모든 명령을 실행하기 위해 배열을 반복한다고 가정 해 보겠습니다. (i = 0 to commands.length) {Runtime.getRuntime (). exec ( "cmd / c start buil.bat"); } 그러면 모든 반복 (모든 명령에 대해)에 대해 명령 창이 열리 며 이는 분명합니다. 하나의 창에서 모든 명령을 실행한다는 것을 어떻게 피할 수 있습니까?
viveksinghggits

1
앞에 "cmd / c"를 넣지 않고 "gradlew.bat"를 직접 호출하는 코드가 있으며 그 코드는 어떻게 든 작동합니다. 그래서 Java 또는 Windows가 어느 시점에서 문제의 일부를 수정했다고 생각합니다. "gradlew"를 실행하려고하면 실패하므로 결국 ".bat"가 여전히 필요합니다.
Trejkaz

Win+R(런타임)은 배치 파일을 직접 실행할 수 있습니다.
Alex78191

21

때로는 스레드 실행 프로세스 시간이 JVM 스레드 대기 프로세스 시간보다 높을 때 호출하는 프로세스가 처리되는 데 시간이 걸릴 때 발생합니다. 다음과 같이 waitFor () 명령을 사용하십시오.

try{    
    Process p = Runtime.getRuntime().exec("file location here, don't forget using / instead of \\ to make it interoperable");
    p.waitFor();

}catch( IOException ex ){
    //Validate the case the file can't be accesed (not enought permissions)

}catch( InterruptedException ex ){
    //Validate the case the process is being stopped by some external situation     

}

이런 식으로 JVM은 스레드 실행 스택을 계속하기 전에 호출하는 프로세스가 완료 될 때까지 중지됩니다.


20
Runtime runtime = Runtime.getRuntime();
try {
    Process p1 = runtime.exec("cmd /c start D:\\temp\\a.bat");
    InputStream is = p1.getInputStream();
    int i = 0;
    while( (i = is.read() ) != -1) {
        System.out.print((char)i);
    }
} catch(IOException ioException) {
    System.out.println(ioException.getMessage() );
}

2
이 코드에 주석을 달고 InputStream이 읽는 이유와 내용, 내가 관심을 갖는 이유를 알려주는 것이 유용 할 것입니다. 또한 배치 파일의 코드가 잘 실행되고 있지만 오류 예외를 발생시킬 수 없습니다.
바룩 아타

2
내 코드에서 "is"와 같은 혼란스러운 변수 이름을 사용하는 것은 나를 미치게 만들 것입니다.
John Fisher

14

Java를 사용하여 배치 파일을 실행하려면 ...

String path="cmd /c start d:\\sample\\sample.bat";
Runtime rn=Runtime.getRuntime();
Process pr=rn.exec(path);`

그렇게해야합니다.


10
질문은 이미 작동하는 솔루션으로 답변되었습니다. 효과가있는 솔루션 만 제공하고 솔루션이 더 좋을 수 있다고 생각하는 이유를 설명해야합니다.
Smamatti 2010

12

ProcessBuilder 는 외부 프로세스를 실행하는 Java 5/6 방법입니다.


2
ProcessBuilder가 Java 5/6으로 이동하는 이유는 무엇입니까?
Dan Polites 2010 년

2
오래된 포스트를 부활시키는 흥미로운 선택 ... ProcessBuilder는 더 많은 제어, 특히 stderr을 stdout으로 쉽게 리디렉션하는 기능을 제공합니다. 또한 설정이 더 직관적이라고 생각하지만 그것은 개인적인 환경입니다
basszero

10

배치 스크립트를 실행하는 데 사용되는 실행 파일 cmd.exe/c플래그를 사용하여 실행할 배치 파일의 이름을 지정하는 것입니다.

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

이론적으로는이 방식으로 Scon을 실행할 수 있어야합니다.

Runtime.getRuntime().exec(new String[]{"scons", "-Q", "implicit-deps-changed", "build\file_load_type", "export\file_load_type"});

편집 : Amara, 이것이 작동하지 않는다고 말합니다. 나열한 오류는 Windows 상자의 Cygwin 터미널에서 Java를 실행할 때 발생하는 오류입니다. 이것이 당신이하는 일입니까? 문제는 Windows와 Cygwin의 경로가 다르기 때문에 Windows 버전의 Java가 Cygwin 경로에서 실행 가능한 scons를 찾지 못한다는 것입니다. 이것이 당신의 문제로 밝혀지면 더 설명 할 수 있습니다.


감사합니다. 여전히 작동하지 않습니다. 해당 코드는 내 앱에서도 실행되지 않습니다. 제시하신 다른 옵션을 시도해 보겠습니다. 다시 한 번 감사드립니다.
Amara

두 번째 대안을 시도 할 때이 오류가 발생합니다. 스레드 "main"java.io.IOException의 예외 : 프로그램 "scons"를 실행할 수 없음 : CreateProcess error = 2, 시스템에서 지정된 파일을 찾을 수 없음
Amara

아니요 Cygwin 터미널이 없습니다. Windows Command 터미널을 사용합니다. 이상합니다. 왜 작동하지 않는지 모르겠습니다. 그것은 나를 완전히 당황하게한다.
Amara

3
Process p = Runtime.getRuntime().exec( 
  new String[]{"cmd", "/C", "orgreg.bat"},
  null, 
  new File("D://TEST//home//libs//"));

jdk1.5 및 jdk1.6으로 테스트 됨

이것은 나를 위해 잘 작동하고 다른 사람들에게도 도움이되기를 바랍니다. 이것을 얻기 위해 나는 더 많은 일을 고생했습니다. :(


1
이것을 추가하십시오 ==> BufferedReader reader = new BufferedReader (new InputStreamReader (p.getInputStream ())); 문자열 라인 = reader.readLine (); while (line! = null) {System.out.println (line); 라인 = reader.readLine (); }
Suren 2013-06-13

2

나는 같은 문제가 있었다. 그러나 때때로 CMD가 내 파일을 실행하지 못했습니다. 그래서 바탕 화면에 temp.bat를 만들고 다음으로이 temp.bat가 내 파일을 실행하고 다음으로 임시 파일이 삭제됩니다.

나는 이것이 더 큰 코드라는 것을 알고 있지만 Runtime.getRuntime (). exec ()조차도 실패했을 때 100 % 저에게 효과적이었습니다.

// creating a string for the Userprofile (either C:\Admin or whatever)
String userprofile = System.getenv("USERPROFILE");

BufferedWriter writer = null;
        try {
            //create a temporary file
            File logFile = new File(userprofile+"\\Desktop\\temp.bat");   
            writer = new BufferedWriter(new FileWriter(logFile));

            // Here comes the lines for the batch file!
            // First line is @echo off
            // Next line is the directory of our file
            // Then we open our file in that directory and exit the cmd
            // To seperate each line, please use \r\n
            writer.write("cd %ProgramFiles(x86)%\\SOME_FOLDER \r\nstart xyz.bat \r\nexit");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // Close the writer regardless of what happens...
                writer.close();
            } catch (Exception e) {
            }

        }

        // running our temp.bat file
        Runtime rt = Runtime.getRuntime();
        try {

            Process pr = rt.exec("cmd /c start \"\" \""+userprofile+"\\Desktop\\temp.bat" );
            pr.getOutputStream().close();
        } catch (IOException ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);

        }
        // deleting our temp file
        File databl = new File(userprofile+"\\Desktop\\temp.bat");
        databl.delete();

1

다음은 잘 작동합니다.

String path="cmd /c start d:\\sample\\sample.bat";
Runtime rn=Runtime.getRuntime();
Process pr=rn.exec(path);

/ c는 무엇을 의미합니까?
Amal lal TL

0

이 코드는 경로 C : / folders / folder에있는 두 개의 commands.bat를 실행합니다.

Runtime.getRuntime().exec("cd C:/folders/folder & call commands.bat");

0

@Isha의 anwser 를 확장하려면 다음을 수행하여 실행 된 스크립트의 반환 된 출력 (사후 실제 시간이 아님)을 얻을 수 있습니다.

try {
    Process process = Runtime.getRuntime().exec("cmd /c start D:\\temp\\a.bat");
    System.out.println(process.getText());
} catch(IOException e) {
    e.printStackTrace();
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.