与从Java应用程序调用的Powershell进程交互
我正在尝试运行一个Java应用程序,它在启动时创建一个新的powershell进程,然后在以后与它进行多次交互。调用powershell.exe并让它执行单个命令并返回输出对我来说很好。如果我不希望powershell进程立即完成/退出,而是保持打开状态,以便写入其outputStream并从inputStream接收结果,则会出现问题与从Java应用程序调用的Powershell进程交互,java,powershell,process,Java,Powershell,Process,我正在尝试运行一个Java应用程序,它在启动时创建一个新的powershell进程,然后在以后与它进行多次交互。调用powershell.exe并让它执行单个命令并返回输出对我来说很好。如果我不希望powershell进程立即完成/退出,而是保持打开状态,以便写入其outputStream并从inputStream接收结果,则会出现问题 String input = "dir"; String[] commandList = {"powershe
String input = "dir";
String[] commandList = {"powershell.exe", "-Command", "dir"};
ProcessBuilder pb = new ProcessBuilder(commandList);
Process p = pb.start();
if(input != null) {
PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(p.getOutputStream())), true);
writer.println(input);
writer.flush();
writer.close();
}
//p.getOutputStream().close();
Gobbler outGobbler = new Gobbler(p.getInputStream());
Gobbler errGobbler = new Gobbler(p.getErrorStream());
Thread outThread = new Thread(outGobbler);
Thread errThread = new Thread(errGobbler);
outThread.start();
errThread.start();
System.out.println("Waiting for the Gobbler threads to join...");
outThread.join();
errThread.join();
System.out.println("Waiting for the process to exit...");
int exitVal = p.waitFor();
System.out.println("\n****************************");
System.out.println("Command: " + "cmd.exe /c dir");
System.out.println("Exit Value = " + exitVal);
List<String> output = outGobbler.getOuput();
input = "";
for(String o: output) {
input += o;
}
System.out.println("Final Output:");
System.out.println(input);
这没有任何效果-当我运行代码时,不会显示第二个dir输出。我还尝试使用powershell.exe选项打开powershell,但不立即关闭:
String[] commandList = {"powershell.exe", "-NoExit", "-Command", "dir"};
但是我的代码挂起了,这意味着使用进程的inputStream的Gobbler不读取任何内容-奇怪的是:他们甚至不读取第一行-必须至少有一些输出
我还尝试在写入第二个“dir”命令后关闭进程的outputStream,但没有改变任何内容
非常感谢您的帮助。
谢谢
Kurt这听起来与另一个过程所产生的过程的性质差不多。我觉得你的行为很标准 这是关键:
p.waitFor()
来自Java文档:
如有必要,使当前线程等待,直到此进程对象表示的进程终止
在PowerShell输出流终止之前,您将无法接收它。当您使用-NoExit
运行时,它永远不会退出,这就是您遇到挂起的原因
如果从Sysinternals运行,您将能够看到Java进程启动了一个子PowerShell进程
所以我不认为你能像记忆中的活物体一样与它互动 谢谢你,安迪。那么调用powershell.exe和cmd.exe之间肯定有区别。因为当我将命令更改为:
String[]commandList={“cmd.exe”、“/k”、“dir”}代码>我实际上可以将另一个“dir”命令写入cmd.exe并获取其反馈。因此在这个场景中,我保持cmd.exe运行(/k开关),并可以向它发送后续命令。我无法对powershell.exe执行相同的操作?@Kurt当您让cmd.exe运行第二个命令时,您是否再次使用pb.start()
运行它?如果是这样的话,我想你可能正在编写另一个cmd.exe。为了确保使用ProcExp查看进程树,以便更好地了解幕后发生的事情。不,我使用了与上面完全相同的代码,无需再次调用pb.start()。当我运行代码时,我可以看到一个cmd.exe和一个conhost.exe正在打开,而不是两个。在输出中,您还可以看到我的第二个“dir”命令被输入到open cmd.exe中:以下是缩写输出:C:\Users\k\Documents\Eclipse Workspace\PipeRedirection目录C:\Users\k\Documents\Eclipse Workspace\PipeRedirection>C:\Users\k\Documents\Eclipse Workspace\PipeRedirection目录最后一个建议,尝试通过cmd.exe间接调用powershell:cmd.exe/k powershell.exe-command dir
。
String[] commandList = {"powershell.exe", "-NoExit", "-Command", "dir"};