2010-11-11 14 views
37

J'essaie d'exécuter des arguments de ligne de commande via Java. Par exemple:Comment exécuter des commandes cmd via Java

// Execute command 
String command = "cmd /c start cmd.exe"; 
Process child = Runtime.getRuntime().exec(command); 

// Get output stream to write from it 
OutputStream out = child.getOutputStream(); 

out.write("cd C:/ /r/n".getBytes()); 
out.flush(); 
out.write("dir /r/n".getBytes()); 
out.close(); 

L'ouvre au-dessus de la ligne de commande, mais n'exécute pas cd ou dir. Des idées? Je cours Windows XP, JRE6.

(j'ai revu ma question d'être plus précis. Les réponses suivantes ont été utiles, mais ne répond pas à ma question.)

+0

Joe, si vous pensez toujours que votre question n'a pas été répondu, je pense que vous devriez donner plus d'informations. Ma réponse fait définitivement ce que vous voulez accomplir, qui est de lister les fichiers dans C: \. Les réponses de Vincent et Carles vous montrent comment exécuter plusieurs commandes shell à partir d'un seul appel 'exec()'. Je ne suis pas sûr de ce que vous n'êtes pas satisfait à ce stade. –

Répondre

3

Le code que vous avez publié démarre trois processus différents chacun avec sa propre commande.Pour ouvrir une invite de commande et puis exécutez une commande essayez ce qui suit (jamais essayé moi-même):

try { 
    // Execute command 
    String command = "cmd /c start cmd.exe"; 
    Process child = Runtime.getRuntime().exec(command); 

    // Get output stream to write from it 
    OutputStream out = child.getOutputStream(); 

    out.write("cd C:/ /r/n".getBytes()); 
    out.flush(); 
    out.write("dir /r/n".getBytes()); 
    out.close(); 
} catch (IOException e) { 
} 
+4

Merci. Cela ouvre la ligne de commande, mais n'exécute pas la commande cd ou dir. – joe

+57

Gee, j'aime les bribes de code avec la clause de non-responsabilité: "Je n'ai jamais essayé moi-même." > _ < –

+4

Ceci ouvre la ligne de commande, mais n'exécute pas la commande cd ou dir, pourquoi? –

2

Essayez cette link

Vous ne pas utiliser « cd » pour changer le répertoire à partir de laquelle exécuter vos commandes. Vous avez besoin du chemin complet de l'exécutable que vous voulez exécuter.

En outre, listant le contenu d'un répertoire est plus facile à faire avec les classes fichier/répertoire

+0

réponse totalement raté le point de la question –

+0

Réponse n'est pas liée à la question –

1

Chacun de vos appels exec crée un processus. Vous deuxième et troisième appels ne s'exécutent pas dans le même processus de coquille que vous créez dans le premier. Essayez de placer toutes les commandes dans un script chauve-souris et de l'exécuter en un seul appel: rt.exec("cmd myfile.bat"); ou similaire

+0

Réponse n'est pas pertinente au code de la question - il n'y a pas d'invocation "autre" exec –

+2

Il y avait quand j'ai répondu, mais la question a été éditée depuis. Veuillez consulter l'historique des révisions pour cette question avant de procéder à une contre-navigation. –

3

Chaque exécution de exec engendre un nouveau processus avec son propre environnement. Donc, votre deuxième invocation n'est en aucun cas liée au premier. Il va juste changer son propre répertoire de travail puis quitter (c'est-à-dire c'est effectivement un no-op).

Si vous souhaitez composer des demandes, vous devez le faire en un seul appel à exec. Bash permet de spécifier plusieurs commandes sur une seule ligne si elles sont séparées par des points-virgules; Windows CMD peut permettre la même chose, et sinon il y a toujours des scripts batch.

As Piotr says, si cet exemple est en fait ce que vous essayez d'atteindre, vous pouvez effectuer la même chose beaucoup plus efficace, de manière efficace et plate-forme en toute sécurité avec les éléments suivants:

String[] filenames = new java.io.File("C:/").list(); 
+0

@Boris - vérifier l'historique des questions, il a été édité dans les deux mois depuis que j'ai posté cette réponse. –

15

Si vous voulez pour exécuter plusieurs commandes dans le shell cmd alors vous pouvez construire une seule commande comme ceci:

rt.exec("cmd /c start cmd.exe /K \"cd c:/ && dir\""); 

This page explique plus.

0

Ceci parce que chaque runtime.exec(..) retourne une classe Process qui doit être utilisé après l'exécution au lieu que d'invoquer d'autres commandes par la classe Runtime

Si vous regardez Process doc vous verrez que vous pouvez utiliser

  • getInputStream()
  • getOutputStream()

sur lequel vous devez travailler en envoyant les commandes successives et en récupérant la sortie.

0

écriture dans le flux à partir du processus est la mauvaise direction. «out» dans ce cas signifie du processus à vous. Essayez d'obtenir/d'écrire dans le flux d'entrée pour le processus et de lire le flux de sortie pour voir les résultats.

61

Je trouve cela dans forums.oracle.com

Permet la réutilisation d'un processus pour exécuter plusieurs commandes dans Windows: http://kr.forums.oracle.com/forums/thread.jspa?messageID=9250051

Vous avez besoin quelque chose comme

String[] command = 
    { 
     "cmd", 
    }; 
    Process p = Runtime.getRuntime().exec(command); 
    new Thread(new SyncPipe(p.getErrorStream(), System.err)).start(); 
    new Thread(new SyncPipe(p.getInputStream(), System.out)).start(); 
    PrintWriter stdin = new PrintWriter(p.getOutputStream()); 
    stdin.println("dir c:\\ /A /Q"); 
    // write any other commands you want here 
    stdin.close(); 
    int returnCode = p.waitFor(); 
    System.out.println("Return code = " + returnCode); 

SyncPipe Classe:

class SyncPipe implements Runnable 
{ 
public SyncPipe(InputStream istrm, OutputStream ostrm) { 
     istrm_ = istrm; 
     ostrm_ = ostrm; 
    } 
    public void run() { 
     try 
     { 
      final byte[] buffer = new byte[1024]; 
      for (int length = 0; (length = istrm_.read(buffer)) != -1;) 
      { 
       ostrm_.write(buffer, 0, length); 
      } 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
    private final OutputStream ostrm_; 
    private final InputStream istrm_; 
} 
+1

c'est en fait la bonne réponse qui fonctionne! –

+4

Bien que le lien est invalide, mais les codes copiés ici sont suffisants. – mrmoment

+0

Fonctionne! C'est bien! merci –

0

Comme j'ai également fait face au même problème et becau Certaines personnes ici ont commenté que la solution ne fonctionnait pas pour eux, voici le lien vers le poste où une solution de travail a été trouvée.

https://stackoverflow.com/a/24406721/3751590

Voir aussi la « mise à jour » dans la meilleure réponse pour l'utilisation de la borne Cygwin

Questions connexes