与从Java应用程序调用的Powershell进程交互

Kur*_*urt 6 java powershell process

我正在尝试运行一个Java应用程序,它在启动时创建一个新的PowerShell进程,然后再多次与它进行交互.调用powershell.exe并让它执行单个命令并返回输出对我来说很好.如果我不希望powershell进程立即完成/退出但保持打开以便我可以写入其outputStream并从inputStream接收结果,则会出现问题.

            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); 
Run Code Online (Sandbox Code Playgroud)

此代码从powershell返回"dir"命令的结果 - 很好.但正如你所看到的,我正在尝试使用第二个"dir"命令

                PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(p.getOutputStream())), true); 
                writer.println(input); 
                writer.flush(); 
Run Code Online (Sandbox Code Playgroud)

这没有任何影响 - 运行我的代码时没有显示第二个dir输出.我还尝试使用powershell.exe选项打开powershell但不立即关闭它:

String[] commandList = {"powershell.exe", "-NoExit", "-Command", "dir"};
Run Code Online (Sandbox Code Playgroud)

但是后来我的代码挂了,这意味着吞噬进程的inputStream的Gobbler没有读任何东西 - 奇怪的是:他们甚至没有读过第一行 - 必须至少有一些输出....

在写完第二个"dir"命令之后,我也试图关闭进程的outputStream - 没有改变任何东西.

任何帮助都非常感谢.谢谢Kurt

And*_*ndi 0

这听起来很适合由另一个进程启动的进程的性质。我认为你正在经历非常标准的行为。

这是关键:p.waitFor()

来自 Java 文档:

如有必要,导致当前线程等待,直到此 Process 对象表示的进程终止。

在 PowerShell 输出流终止之前,您将无法接收它。当您运行时-NoExit它永远不会退出,这就是您遇到挂起的原因。

如果您从 Sysinternals 运行ProcExp,您将能够看到 Java 进程启动子 PowerShell 进程。

因此,我认为您无法像它是内存中的活动对象一样与它进行交互。