Взаимодействие с процессом Powershell, вызываемым из приложения Java - PullRequest
6 голосов
/ 05 января 2012

Я пытаюсь запустить приложение 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); 

Этот код возвращает результат команды "dir" из powershell - отлично.Но, как вы можете видеть, я пытаюсь запустить вторую команду «dir», используя

                PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(p.getOutputStream())), true); 
                writer.println(input); 
                writer.flush(); 

Это никак не влияет - никакой второй вывод dir не отображается, когда я запускаю свой код.Я также экспериментировал с параметром powershell.exe, чтобы открыть PowerShell, но не закрывать его сразу:

String[] commandList = {"powershell.exe", "-NoExit", "-Command", "dir"};

Но затем мой код зависает, что означает, что Gobbler, который использует inputStream процесса, ничего не читаеткак ни странно: они даже не читают первую строку - должен быть хоть какой-то вывод ...

Я также пытался закрыть outputStream процесса после записи в него второй команды "dir"- ничего не изменилось.

Любая помощь высоко ценится.Спасибо Курт

1 Ответ

0 голосов
/ 05 января 2012

Это звучит как раз для природы процесса, ускоренного другим процессом.Я думаю, вы испытываете довольно стандартное поведение.

Это ключ: p.waitFor()

Из документов Java:

заставляет текущий поток ждать,при необходимости, до тех пор, пока процесс, представленный этим объектом Process, не завершится.

Вы не сможете получить поток вывода PowerShell, пока он не завершится.Когда вы запускаете с -NoExit, он никогда не завершается, поэтому вы зависаете.

Если вы запустите ProcExp из Sysinternals, вы сможете увидеть, как ваш Java-процесс ускоряетсядочерний процесс PowerShell.

Так что я не думаю, что вы сможете взаимодействовать с ним, как будто это живой объект в памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...