使用CMD作为过程

我正试图在Windows上直接运行命令(Linux上的终端)。 我有以下代码。 它表现得非常奇怪。 首先,运行时程序不会打印任何内容。 其次,当调试并逐步执行时,程序将打印默认的CMD文本和输入行。 最后,我似乎无法写入CMD,因此它将执行命令。 这是我的代码。 我猜它可能是一个线程问题,但我不熟悉Runtime。

Runtime r = Runtime.getRuntime(); try { Process p = r.exec("cmd"); InputStream iStream = p.getInputStream(); BufferedReader sReader = new BufferedReader(new InputStreamReader(iStream)); while(sReader.ready()) { System.out.print((char)sReader.read()); } OutputStream oStream = p.getOutputStream(); BufferedWriter sWriter = new BufferedWriter(new OutputStreamWriter(oStream)); sWriter.write("mkdir test"); sWriter.newLine(); while(sReader.ready()) { System.out.print((char)sReader.read()); } } catch(Exception e) { e.printStackTrace(); } 

调试并逐步执行时的输出,(运行时不显示输出)

 Microsoft Windows XP [Version 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. D:\workspaces\Maven\Command Line> 

可能会发生一些事情。 一个是参数没有按照执行过程的方式正确传递。 另一个,就像@zacheusz提到的那样,输出可能来自错误流而不是输入流。

ProcessBuilder可以帮助完成这两项工作,允许轻松构建命令列表以及合并输入和错误流的function。 我建议尝试使用它:

 Process p = null; try { List cmd = new LinkedList(); cmd.add("executable"); cmd.add("-arg1"); cmd.add("value1"); cmd.add("-arg2"); ProcessBuilder pb = new ProcessBuilder(cmd); pb.redirectErrorStream(true); p = pb.start(); BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); while (input.ready()) { String line = input.readLine(); System.out.println("From process: "+line); } input.close(); } catch (IOException e) { this.logMessage("IOException caught: "+e.getMessage()); e.printStackTrace(); } 

你需要在一个线程中完成这项工作。 例如,记录标准输出:

 Process process = Runtime.getRuntime().exec(command); LogStreamReader lsr = new LogStreamReader(process.getInputStream()); Thread thread = new Thread(lsr, "LogStreamReader"); thread.start(); public class LogStreamReader implements Runnable { private BufferedReader reader; public LoggingStreamReader(InputStream is) { this.reader = new BufferedReader(new InputStreamReader(is)); } public void run() { try { String line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } reader.close(); } catch (IOException e) { e.printStackTrace(); } } } 

然后你需要第二个线程来进行输入处理。 你可能想像stdout一样处理stderr。

几年前我在网上发现了这个代码。 我不记得在哪里。 它已经很老了所以现在可能会有更好的东西。

  private void executeCommand(String cmd) { try { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec(cmd); // any error message? StreamHandler errorGobbler = new StreamHandler(proc.getErrorStream(), "ERR"); // any output? StreamHandler outputGobbler = new StreamHandler(proc.getInputStream(), "OUT"); // kick them off errorGobbler.start(); outputGobbler.start(); // any error??? int exitVal = proc.waitFor(); System.out.println("ExitValue: " + exitVal); } catch (Exception e) { e.printStackTrace(); } } 

和class级:

 import java.util.*; import java.io.*; public class StreamHandler extends Thread { InputStream is; String type; OutputStream os; StringBuffer output; StreamHandler(InputStream is, String type) { this(is, type, null); } StreamHandler(InputStream is, String type, OutputStream redirect) { this.is = is; this.type = type; this.os = redirect; output = new StringBuffer(100); } public void run() { try { PrintWriter pw = null; if (os != null) pw = new PrintWriter(os); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line=null; while ( (line = br.readLine()) != null) { if (pw != null) pw.println(line); System.out.println(type + ">" + line); } if (pw != null) pw.flush(); } catch (IOException ioe) { ioe.printStackTrace(); } } } 

通常cmdterminal负责为它们执行的程序设置标准io,因此我认为您不能通过输入/输出流与它们进行通信。 在Linux的情况下,它实际上是在终端内运行的shell执行命令,而不是终端本身。 Windows也可能做一些时髦的事情。

您可以执行命令而无需将cmd.exe实际硬编码到代码中。

 public static void main(String[] args) { //cmd = the command youw ill be using String cmd = "ipconfig"; Runtime r = Runtime.getRuntime(); Process p; try { p = r.exec(cmd); BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println(inputLine); } } catch (IOException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } } 

cmd尝试运行命令提示符,

要正确运行该命令,您需要以下命令行

cmd.exe -c ipconfig.exe

-c表示在命令行的其余部分上运行命令