2009-03-05 31 views
96

Trong ứng dụng Java của tôi, tôi muốn chạy một tập tin thực thi gọi là "scons -Q implicit-deps-changed build\file_load_type export\file_load_type"Làm cách nào để chạy một tệp lô từ Ứng dụng Java của tôi?

Dường như tôi thậm chí không thể lấy tập tin thực thi của mình. Tôi hết ý tưởng.

Đây là những gì tôi có trong Java:

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

Trước đây, tôi đã có một tập tin Python Sconscript mà tôi muốn chạy nhưng kể từ đó đã không làm việc tôi quyết định tôi sẽ gọi kịch bản thông qua một tập tin thực thi nhưng phương pháp đó vẫn chưa thành công.

Trả lời

155

Tệp hàng loạt không thực thi được. Họ cần một ứng dụng để chạy chúng (ví dụ: cmd).

Trên UNIX, tệp tập lệnh có shebang (#!) Ở đầu tệp để chỉ định chương trình thực thi nó. Kích đúp vào Windows được thực hiện bởi Windows Explorer. CreateProcess không biết gì về điều đó.

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

Lưu ý: Với lệnh start \"\", một cửa sổ lệnh riêng biệt sẽ được mở ra với một tiêu đề trống và bất kỳ đầu ra từ các tập tin thực thi sẽ được hiển thị ở đó. Nó cũng nên làm việc chỉ với `cmd/c build.bat ', trong trường hợp đó, đầu ra có thể được đọc từ tiến trình con trong Java nếu muốn,

+0

Đối với tôi nó nói Windows không thể tìm thấy "build.bat". Vậy tôi nên đặt tập tin này ở đâu? Hoặc làm thế nào tôi nên cho con đường. Bất kỳ đề xuất? – nanospeck

+1

cho phép nói rằng tôi có một mảng lệnh và sau đó lặp lại mảng đó để thực hiện tất cả các lệnh cho (i = 0 đến commands.length) { Runtime.getRuntime(). Exec ("cmd/c start buil.bat") ; } sau đó cho mỗi lần lặp (đối với mọi lệnh) một cửa sổ lệnh đang được mở, điều này hiển nhiên. Làm thế nào có thể tránh được rằng tôi có nghĩa là thực hiện tất cả các lệnh trên một cửa sổ. – viveksinghggits

+0

Chúng tôi có một số mã được gọi trực tiếp "gradlew.bat" mà không đặt "cmd/c" công cụ ở phía trước của nó, và mã đó đang làm việc bằng cách nào đó. Vì vậy, tôi đoán Java hoặc Windows cố định một phần của vấn đề tại một số điểm. Nếu chúng ta cố gắng để exec "gradlew", mà không thành công mặc dù, do đó rõ ràng ".bat" vẫn còn cần thiết vào cuối. – Trejkaz

9

Các thực thi sử dụng để chạy các kịch bản hàng loạt là cmd.exe trong đó sử dụng các /c cờ để chỉ định tên của tập tin batch để chạy:

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

Về mặt lý thuyết, bạn cũng sẽ có thể chạy SCons theo cách này, mặc dù Tôi chưa thử nghiệm điều này:

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

EDIT: Amara, bạn nói rằng điều này không hoạt động. Lỗi bạn liệt kê là lỗi bạn sẽ nhận được khi chạy Java từ một thiết bị đầu cuối Cygwin trên một hộp Windows; đây là những gì bạn đang làm? Vấn đề là Windows và Cygwin có các đường dẫn khác nhau, vì vậy phiên bản Java của Windows sẽ không tìm thấy các scons thực thi trên đường dẫn Cygwin của bạn. Tôi có thể giải thích thêm nếu điều này hóa ra là vấn đề của bạn.

+0

Cảm ơn bạn. Nó vẫn không hoạt động - đoạn mã đó thậm chí không thực thi trong ứng dụng của tôi. Tôi sẽ thử tùy chọn khác mà bạn đã trình bày. Cảm ơn một lần nữa. – Amara

+0

Khi tôi thử phương án thứ hai, nó cho tôi lỗi này: Ngoại lệ trong chủ đề "chính" java.io.IOException: Không thể chạy chương trình "scons": Lỗi CreateProcess = 2, Hệ thống không thể tìm thấy tệp được chỉ định – Amara

+0

Không, tôi không có thiết bị đầu cuối Cygwin. Tôi sử dụng Windows Command terminal. Thật kỳ lạ - Tôi không biết tại sao nó không hoạt động. Nó hoàn toàn cản trở tôi. – Amara

11

ProcessBuilder là cách 5/6 Java để chạy các tiến trình bên ngoài.

+1

Tại sao ProcessBuilder lại là con đường để đi trong Java 5/6? –

+2

Lựa chọn thú vị để hồi sinh lại bài đăng cũ ... ProcessBuilder cung cấp nhiều quyền kiểm soát hơn, đặc biệt là khả năng chuyển hướng stderr dễ dàng sang chế độ stdout. Tôi cũng tìm thấy các thiết lập trực quan hơn, nhưng đó là một pref cá nhân – basszero

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

Nó sẽ hữu ích để bình luận mã này và cho chúng tôi biết tại sao và những gì InputStream là đọc, và tại sao tôi quan tâm. Ngoài ra, mã cho các tập tin thực thi đang chạy độc đáo, nhưng tôi không thể làm cho nó để nâng cao một lỗi Ngoại lệ. –

+0

Nó sẽ khiến tôi cảm thấy có một tên biến khó hiểu như "is" trong mã của tôi. –

20

Đôi khi các chủ đề thời gian quá trình thực hiện cao hơn JVM chủ đề thời gian chờ đợi quá trình, nó sử dụng xảy ra khi quá trình bạn đang gọi mất một thời gian để được xử lý, sử dụng wAITFOR() lệnh như sau:

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  

} 

Bằng cách này, JVM sẽ dừng cho đến khi proc ess bạn đang gọi được thực hiện trước khi nó tiếp tục với ngăn xếp thực thi luồng.

13

Để chạy các file batch sử dụng java nếu đó là bạn đang nói về ...

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

này nên làm điều đó.

+8

Câu hỏi đã được trả lời bằng một giải pháp làm việc. Bạn chỉ nên cung cấp các giải pháp mà bạn biết đang hoạt động và mô tả lý do tại sao bạn cho rằng giải pháp của mình có thể tốt hơn. – Smamatti

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

thử nghiệm với jdk1.5 và jdk1.6

Điều này làm việc tốt cho tôi, hy vọng nó cũng giúp người khác. để có được điều này tôi đã đấu tranh nhiều ngày. :(

+1

thêm this ==> BufferedReader reader = new BufferedReader (new InputStreamReader (p.getInputStream())); \t \t \t Chuỗi line = reader.readLine(); \t \t \t \t \t \t \t while (dòng = null) { \t \t \t \t System.out.println (dòng); \t \t \t \t line = reader.readLine(); \t \t \t} – Suren

0

Sau đây là làm việc tốt:

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

tôi đã cùng một vấn đề Tuy nhiên đôi khi CMD thất bại trong việc chạy các file của tôi Đó là lý do tôi tạo ra một temp.bat trên máy tính để bàn của tôi, bên cạnh tạm thời này.. .bat sẽ chạy tập tin của tôi, và tiếp theo tập tin tạm thời sẽ bị xóa

Tôi biết đây là một mã lớn hơn, tuy nhiên đã làm việc cho tôi trong 100% ngay cả khi Runtime.getRuntime(). exec() thất bại.

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

Mã này sẽ thực hiện hai lệnh.bat tồn tại trong đường dẫn C:/folders/folder.

Runtime.getRuntime().exec("cd C:/folders/folder & call commands.bat"); 
Các vấn đề liên quan