Estoy tratando de ejecutar una aplicación Java que crea un nuevo proceso de PowerShell al inicio y luego interactúa con él varias veces. Llamar a powershell.exe y hacer que ejecute un solo comando y devolver la salida funciona bien para mí. El problema surge si no quiero que el proceso de PowerShell termine/salga inmediatamente, sino que permanezca abierto para poder escribir en su outputStream y recibir los resultados de InputStream.Interactuar con el proceso Powershell llamado desde la aplicación Java
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);
Este código devuelve el resultado del comando "dir" de un powershell - bien. Pero como se puede ver, estoy tratando de ejecutar un segundo comando "dir" usando
PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(p.getOutputStream())), true);
writer.println(input);
writer.flush();
Esto no tiene ningún efecto en absoluto - no hay segunda salida dir se muestra cuando corro mi código. También he experimentado con una opción para abrir el powershell.exe PowerShell pero no cerrarla de inmediato:
String[] commandList = {"powershell.exe", "-NoExit", "-Command", "dir"};
Pero entonces mis cuelga de código, es decir, de que consumen flujoEntrada del proceso no lee nada del pavo - curiosamente : ni siquiera leen la primera línea, debe haber al menos alguna salida ...
También traté de cerrar el outputStream del proceso después de escribir el segundo comando "dir" en él - no lo hice Cambia cualquier cosa.
Cualquier ayuda es muy apreciada. Gracias Kurt
Gracias Andy. Entonces debe haber una diferencia entre llamar powershell.exe y cmd.exe. Porque cuando cambio el comando a esto: 'String [] commandList = {" cmd.exe ","/k "," dir "};' De hecho, puedo escribir otro comando "dir" al cmd.exe y obtener su retroalimentación. Por lo tanto, en este escenario, mantengo el cmd.exe en ejecución (modificador/k) y puedo enviarle los comandos subsiguientes. ¿De ninguna manera puedo hacer lo mismo con powershell.exe? – Kurt
@Kurt Cuando tienes cmd.exe ejecuta un segundo comando ¿lo estás ejecutando con 'pb.start()' de nuevo? Si es así, creo que podría estar girando otro cmd.exe. Para asegurarse de ver el árbol de procesos con ProcExp para obtener una mejor visión de lo que está sucediendo detrás de las escenas. –
no, uso exactamente el mismo código que el anterior, sin una segunda llamada a pb.start(). Cuando ejecuto el código, puedo ver una apertura de cmd.exe y una de conhost.exe, no dos. En la salida también puede ver que mi segundo comando "dir" se ingresa en el cmd abierto.exe: – Kurt