2017-02-20 3 views
1

J'essaie d'exécuter la commande Windows cmd en java, l'alimenter avec des commandes et imprimer la sortie ou l'erreur sur la console. Cependant, ma tentative se bloque après l'impression du message de la bannière. Voici le code.java Runtime.exec pour exécuter le shell interactif se bloque

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.io.OutputStreamWriter; 

public class Application { 

    public static void main(String[] args) throws IOException, InterruptedException { 

     Process exec = Runtime.getRuntime().exec("cmd"); 

     InputStream procOut = exec.getInputStream(); 
     InputStream procErrOut = exec.getErrorStream(); 
     OutputStream procIn = exec.getOutputStream(); 

     new StreamConsumer(procOut).run(); 
     new StreamConsumer(procErrOut).run(); 

     ByteArrayOutputStream byos = new ByteArrayOutputStream(); 
     byos.write("ping 1.1.1.1".getBytes()); 
     byos.writeTo(procIn); 
     byos.flush(); 
     procIn.flush(); 

     int ret = exec.waitFor(); 
     System.out.printf("Process exited with value %d", ret); 
    } 

    public static class StreamConsumer implements Runnable { 

     private InputStream input; 

     public StreamConsumer(InputStream input) { 
      this.input = input; 
     } 

     @Override 
     public void run() { 
      BufferedReader reader = new BufferedReader(new InputStreamReader(input)); 
      String line; 
      try { 
       while ((line = reader.readLine()) != null) { 
        System.out.println(line); 
       } 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } finally { 
       try { 
        reader.close(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 

    } 
} 

Et voici la sortie

Microsoft Windows [Version 6.1.7601] 
Copyright (c) 2009 Microsoft Corporation. All rights reserved. 
** program hangs ** 

Pourquoi ne se bloque et aucun ping est exécuté le programme (ou imprimé)? Je comprends que les flux doivent être consommés pour éviter de se bloquer (ce que je fais dans un thread séparé), mais ça reste bloqué. Ai-je mal compris comment le flux de sortie est redirigé vers un shell interactif ou quel est le problème?

+0

Juste une supposition, mais le programme pourrait faire le ping et puis d'attendre toujours pour plus d'entrée (puisqu'il est cmd). Vous ne collectez aucune sortie. –

+0

Peut être lié, mais 'StreamConsumer' n'est jamais utilisé non plus. –

Répondre

1

Vous devez commencer fils consommer les sorties:

 new Thread(new StreamConsumer(procOut)).start(); 
     new Thread(new StreamConsumer(procErrOut)).start(); 
+0

Je me sens stupide, ça fait un certain temps depuis que j'ai utilisé Threads –

+0

Cela a résolu le problème, mais il y a encore un problème, l'invite 'C: \>' n'est pas imprimée tant que l'entrée n'est pas donnée. Pourquoi donc? –

+0

@TuomasToivonen probablement parce que les sorties sont consommées une ligne à la fois –