2010-11-11 43 views
37

Tôi đang cố gắng thực thi đối số dòng lệnh thông qua Java. Ví dụ:Cách thực hiện lệnh cmd qua Java

// Execute command 
String command = "cmd /c start cmd.exe"; 
Process child = Runtime.getRuntime().exec(command); 

// Get output stream to write from it 
OutputStream out = child.getOutputStream(); 

out.write("cd C:/ /r/n".getBytes()); 
out.flush(); 
out.write("dir /r/n".getBytes()); 
out.close(); 

Trên đây mở ra những dòng lệnh nhưng không thực hiện cd hoặc dir. Bất kỳ ý tưởng? Tôi đang chạy Windows XP, JRE6.

(Tôi đã sửa đổi câu hỏi của tôi là cụ thể hơn. Những câu trả lời sau đây là hữu ích nhưng không trả lời câu hỏi của tôi.)

+0

joe, nếu bạn vẫn cảm thấy rằng câu hỏi của bạn chưa được trả lời Tôi nghĩ rằng bạn nên cung cấp nền hơn. Câu trả lời của tôi chắc chắn làm những gì bạn muốn đạt được, đó là danh sách các tập tin trong C: \. Câu trả lời của Vincent và Carles chỉ cho bạn cách chạy nhiều lệnh shell từ một lệnh gọi 'exec()' duy nhất. Tôi không chắc chắn những gì bạn không hài lòng với tại thời điểm này. –

Trả lời

3

Mã bạn đã đăng bắt đầu ba quy trình khác nhau với mỗi lệnh riêng.Để mở một dấu nhắc lệnh và sau đó chạy một lệnh thử sau (không bao giờ thử bản thân mình):

try { 
    // Execute command 
    String command = "cmd /c start cmd.exe"; 
    Process child = Runtime.getRuntime().exec(command); 

    // Get output stream to write from it 
    OutputStream out = child.getOutputStream(); 

    out.write("cd C:/ /r/n".getBytes()); 
    out.flush(); 
    out.write("dir /r/n".getBytes()); 
    out.close(); 
} catch (IOException e) { 
} 
+4

Cảm ơn. Điều này sẽ mở ra dòng lệnh, nhưng nó không thực hiện lệnh cd hoặc dir. – joe

+57

Gee, tôi yêu đoạn mã với tuyên bố từ chối trách nhiệm: "Không bao giờ tự mình thử." > _ < –

+4

Điều này sẽ mở ra dòng lệnh, nhưng nó không thực hiện lệnh cd hoặc dir, tại sao? –

2

Hãy thử điều này link

Bạn không sử dụng "cd" để thay đổi thư mục để chạy các lệnh của bạn. Bạn cần đường dẫn đầy đủ của tệp thực thi mà bạn muốn chạy.

Ngoài ra, việc liệt kê nội dung của thư mục dễ dàng hơn với các lớp Tệp/Thư mục

+0

câu trả lời hoàn toàn bị bỏ lỡ các điểm của câu hỏi –

+0

Trả lời không liên quan đến câu hỏi –

1

Mỗi cuộc gọi exec của bạn tạo một quy trình. Bạn gọi thứ hai và thứ ba không chạy trong cùng một quá trình shell bạn tạo trong lần đầu tiên. Thử đặt tất cả các lệnh vào một tập lệnh bat và chạy nó trong một cuộc gọi: rt.exec("cmd myfile.bat"); hoặc tương tự

+0

Trả lời không liên quan đến mã của câu hỏi - không có lời gọi exec "khác" –

+2

Có khi tôi trả lời, nhưng câu hỏi đã được chỉnh sửa kể từ đó. Vui lòng xem lịch sử sửa đổi cho câu hỏi này trước khi downvoting. –

3

Mỗi lần thực hiện exec sẽ sinh ra một quy trình mới với môi trường riêng của nó. Vì vậy, lời gọi thứ hai của bạn không được kết nối với lần đầu tiên theo bất kỳ cách nào. Nó sẽ chỉ thay đổi thư mục hoạt động riêng của nó và sau đó thoát ra (tức là nó không hiệu quả).

Nếu bạn muốn soạn yêu cầu, bạn sẽ cần thực hiện việc này trong một cuộc gọi đến exec. Bash cho phép nhiều lệnh được chỉ định trên một dòng nếu chúng được phân tách bằng dấu chấm phẩy; Windows CMD có thể cho phép như vậy, và nếu không phải luôn có các kịch bản lệnh batch.

As Piotr says, nếu ví dụ này là thực những gì bạn đang cố gắng để đạt được, bạn có thể thực hiện điều tương tự nhiều hiệu quả hơn, có hiệu quả và nền tảng một cách an toàn với những điều sau:

String[] filenames = new java.io.File("C:/").list(); 
+0

@ Boris - kiểm tra lịch sử câu hỏi, nó đã được chỉnh sửa trong hai tháng kể từ khi tôi đăng câu trả lời này. –

15

Nếu bạn muốn để chạy một số lệnh trong trình bao cmd thì bạn có thể tạo một lệnh duy nhất như sau:

rt.exec("cmd /c start cmd.exe /K \"cd c:/ && dir\""); 

This page giải thích thêm.

0

này vì mỗi runtime.exec(..) trả về một lớp Process nên được sử dụng sau khi thực hiện thay vào đó gọi lệnh khác bởi lớp Runtime

Nếu bạn nhìn vào Process doc bạn sẽ thấy rằng bạn có thể sử dụng

  • getInputStream()
  • getOutputStream()

mà bạn nên làm việc bằng cách gửi các lệnh liên tiếp và truy xuất đầu ra ..

0

Viết cho luồng ra từ quá trình này là sai hướng. 'ra' trong trường hợp đó có nghĩa là từ quá trình cho bạn. Hãy thử nhận/ghi vào luồng đầu vào cho quá trình và đọc từ luồng đầu ra để xem kết quả.

61

Tôi thấy điều này trong forums.oracle.com

Cho phép tái sử dụng một quá trình để thực hiện nhiều lệnh trong Windows: http://kr.forums.oracle.com/forums/thread.jspa?messageID=9250051

Bạn cần một cái gì đó giống như

String[] command = 
    { 
     "cmd", 
    }; 
    Process p = Runtime.getRuntime().exec(command); 
    new Thread(new SyncPipe(p.getErrorStream(), System.err)).start(); 
    new Thread(new SyncPipe(p.getInputStream(), System.out)).start(); 
    PrintWriter stdin = new PrintWriter(p.getOutputStream()); 
    stdin.println("dir c:\\ /A /Q"); 
    // write any other commands you want here 
    stdin.close(); 
    int returnCode = p.waitFor(); 
    System.out.println("Return code = " + returnCode); 

SyncPipe Class:

class SyncPipe implements Runnable 
{ 
public SyncPipe(InputStream istrm, OutputStream ostrm) { 
     istrm_ = istrm; 
     ostrm_ = ostrm; 
    } 
    public void run() { 
     try 
     { 
      final byte[] buffer = new byte[1024]; 
      for (int length = 0; (length = istrm_.read(buffer)) != -1;) 
      { 
       ostrm_.write(buffer, 0, length); 
      } 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
    private final OutputStream ostrm_; 
    private final InputStream istrm_; 
} 
+1

đây thực sự là câu trả lời đúng mà hoạt động! –

+4

Tuyệt vời là liên kết không hợp lệ nhưng mã được sao chép ở đây là đủ. – mrmoment

+0

Hoạt động! Điều đó thật tuyệt! cảm ơn –

0

Vì tôi cũng phải đối mặt với cùng một vấn đề và becau se một số người ở đây nhận xét rằng giải pháp không hoạt động cho họ, đây là liên kết tới bài đăng nơi giải pháp làm việc đã được tìm thấy.

https://stackoverflow.com/a/24406721/3751590

Ngoài ra hãy xem phần "Update" trong câu trả lời tốt nhất cho việc sử dụng Cygwin terminal

Các vấn đề liên quan