IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API standards et tierces Java Discussion :

[Runtime] executer une ligne de commande cmd à partir de java


Sujet :

API standards et tierces Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 67
    Points : 40
    Points
    40
    Par défaut [Runtime] executer une ligne de commande cmd à partir de java
    Bonsoir à tous.

    J'ai un petit probleme, en effet je travail sur une application qui consiste à executer une commande (cmd) à partir de java sous Windows XP.

    Mon programme marche tres bien quand il s'agit par exemple d'executer des fichiers .exe mais pour les fichiers .bat ou pour executer directement des commandes cmd ca ne marche pas.

    J'ai fait pas mal de recherche sur le net, mon programme devrait semble t-il fonctionner.

    Je suis par exemple voir du coté de :

    http://ydisanto.developpez.com/tutoriels/j2se/runtime/

    qui est tres bien expliqué mais mon programme ne marche pas.

    Voici mon programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    package org.commande.test ;
     
    public class Main {
     
    	public static void main(String[] args) {
     
    	      String [] cmd = new String[3];
    	      cmd[0] = "cmd.exe" ;
    	      cmd[1] = "/C" ;
    	      //cmd[2] = "C:\\video\\fichier.bat"; 
    	      cmd[2] = "cd \"C:\\video\"" + " && dir"; 
     
    		//cmd = "C:\\WINDOWS\\system32\\cmd.exe" ;
     
    		try {
    			System.out.println("test ");
    			Runtime r = Runtime.getRuntime();
    			Process p = r.exec(cmd);
    			//Process p = r.exec(new String[] { "cmd.exe", "/C", "echo bonjour" } ); 
    			p.waitFor();//si l'application doit attendre a ce que ce process fini
    		}catch(Exception e) {
    			//System.out.println("erreur d'execution " + cmd + e.toString());
    			System.out.println("erreur d'execution " + e.toString());
    		}
    	}
    }
    je precise que la ligne de commande que j'utilise marche tres bien quand je la tappe directement dans l'invite de commande.

    J'ai constaté egalement dans mon cas quand je teste sur des fichiers .exe ca marche à tous les coups sauf justement quand je veux lancer cmd.exe.

    Je pense qu'il y'a un lien avec mon probleme mais je me trompe peut etre.

    Si quelqu'un peut m'aider ce serait vraiment tres sympa.

    Cordialement,

  2. #2
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Points : 5 778
    Points
    5 778
    Par défaut
    Apparement tu as sauté une partie du tutoriel :
    il est nécessaire de consommer tous les flux de sortie. De plus, chaque flux doit être géré dans un thread différent.
    cf III-B. Consommation des flux.
    Je viens d'essayer ta ligne de commande et ça marche très bien .

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 67
    Points : 40
    Points
    40
    Par défaut
    Bonsoir y@m's.

    Merci pour ta reponse. En effet tu as raison je ne l'ai pas vraiment lu en entier, je suis aller a la fin, pensant que seul cette partie me semblait necessaire.

    J'ai vais bien le relire et essayer de comprendre cette partie.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 67
    Points : 40
    Points
    40
    Par défaut
    Bonsoir le y@m's.

    Apres tes conseils j'ai donc bien relu le tuto. je gere maintenant mon flux dans un thread.

    Je me suis peut etre trompé mais mon code ne marche toujours pas.

    Voici mon code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    package org.commande.test ;
     
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
     
    public class Main {
     
    	public static void main(String[] args) throws IOException {
     
    		Runtime runtime = Runtime.getRuntime();
    		final Process process = runtime.exec(new String[] { "cmd.exe", "/C", "cd \"C:\\video\"" + " && dir" } );
    		//final Process process = runtime.exec(cmd);
     
    		//Consommation de la sortie standard de l'application externe dans un Thread separe
    		new Thread() {
    			public void run() {
    				try {
    					BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    					String line = "";
    					try {
    						while((line = reader.readLine()) != null) {
    							// Traitement du flux de sortie de l'application si besoin est
    						}
    					} finally {
    						reader.close();
    					}
    				} catch(IOException ioe) {
    					ioe.printStackTrace();
    				}
    			}
    		}.start();
    	}
    }
    J'ai peut etre oublié ou mal fait quelque chose. Si tu vois un probleme, ce serait sympa de me signaler.

    Merci encor

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 67
    Points : 40
    Points
    40
    Par défaut
    Juste un petit détail, j'avais pensé à étendre Thread pour ma classe Main mais comme la aussi ca ne marche pas je t'ai mis le code sans.

  6. #6
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Points : 5 778
    Points
    5 778
    Par défaut
    C'est normal que rien ne s'affiche puisque tu n'écris pas le flux de sortie (que tu récupère via le getInputStream()) sur la console .
    Remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    // Traitement du flux de sortie de l'application si besoin est
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println(line);
    Remarque : même si dans ce cas cela n'a pas d'incidence dans ce cas, il est préférable de consommer également le flux d'erreur (récupéré via le getErrorStream()) .

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 67
    Points : 40
    Points
    40
    Par défaut
    Bonjour le y@m's.

    De nouveau je te remercie pout ta reponse.

    J'ai bien fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    System.out.println(line) ;
    Cette fois ci ca marche bien.

    Dans mon cas ce qui est bizarre est que le dir marche bien mais le
    n'est pas pris en compte, en fait ca me fait un dir sur le repertoire de mon projet eclipse.

    Pourtant cette commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    cd "C:\video" && dir
    marche quand je la tappe directement dans le CMD.

    Ma commande a pourtant l'air juste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    final Process process = runtime.exec(new String[] { "cmd.exe", "/C", "cd \"C:\\video\"" + " && dir" } );
    je teste bien l'affichage de la commande a part :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    String test = "cd \"C:\\video\"" + " && dir" ;
    System.out.println(test) ;
    Cela m'affiche bien sur la console :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    cd "C:\video" && dir
    Code qui marche bien directement sur le CMD.

    Donc je ne vois pas trop ce qui cloche.

    Si tu vois un probleme dans mon ligne de commande (process) merci de me faire signe.

  8. #8
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    On pourrait voir ton code actuel ? Est-ce que tu lis bien le flux d'erreur ? Et ferme toujours le flux d'entrée (surtout si tu ne l'utilises pas).

    a++

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 67
    Points : 40
    Points
    40
    Par défaut
    Bonjour adiGuba.

    Merci pour ta réponse.

    Voici mon code actuel.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    package org.commande.test ;
     
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
     
    public class Main {  
     
    	public static void main(String[] args) throws IOException {
     
    		String testCommande = "cd \"C:\\video\"" + " && dir" ;
     
    		System.out.println(testCommande) ;
     
    		Runtime runtime = Runtime.getRuntime();
    		final Process process = runtime.exec(new String[] { "cmd.exe", "/C", "cd \"C:\\video\"" + " && dir" } );
    		//final Process process = runtime.exec(cmd);
     
    		//Consommation de la sortie standard de l'application externe dans un Thread separe
    		new Thread() {
    			public void run() {
    				try {
    					BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    					String line = "";
    					try {
    						while((line = reader.readLine()) != null) {
    							// Traitement du flux de sortie de l'application si besoin est
    							System.out.println(line);
    						}
    					} finally {
    						reader.close() ;    
    					}
    				} catch(IOException ioe) {
    					ioe.printStackTrace();
    				}
    			}
    		}.start();
     
    		//Consommation de la sortie d'erreur de l'application externe dans un Thread separe
    		new Thread() {
    			public void run() {
    				try {
    					BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
    					String line = "";
    					try {
    						while((line = reader.readLine()) != null) {
    							// Traitement du flux d'erreur de l'application si besoin est
    							System.out.println(line);
    						}
    					} finally {
    						reader.close();
    					}
    				} catch(IOException ioe) {
    					ioe.printStackTrace();
    				}
    			}
    		}.start();
    	}
    }
    Je lis bien le flux d'erreur car quand je tappe une commande fausse j'ai bien un message d'erreur.

    Je pense egalement que je ferme le flux d'entrée.
    sans en etre sur.

    Donc je ne vois pas trop. Merci pour ton aide

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 67
    Points : 40
    Points
    40
    Par défaut
    Voici le resultat exact que j'ai sur la console :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    cd "C:\video" && dir
     Le volume dans le lecteur D s'appelle Donnees
     Le num‚ro de s‚rie du volume est 8480-9495
     
     R‚pertoire de D:\eclipse\workspace\TestCommande
     
    09/05/2007  09:45    <REP>          .
    09/05/2007  09:45    <REP>          ..
    09/05/2007  09:45               232 .classpath
    09/05/2007  09:45               388 .project
    09/05/2007  09:45    <REP>          bin
    09/05/2007  09:45    <REP>          src
                   2 fichier(s)              620 octets
                   4 R‚p(s)  27ÿ773ÿ009ÿ920 octets libres
    il fait le dir sur mon projet elipse TestCommande.

  11. #11
    Membre actif
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    333
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 333
    Points : 295
    Points
    295
    Par défaut
    tu executes ton code alors que tu te trouve sur le lecteur d: (eclipse workspace )


    or
    D> cd C:\LOCAL
    donne
    D>

    donc de mon point de vue c normal ce qu il te rend

    je te conseille d utiliser :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Process 	exec(String[] cmdarray, String[] envp, File dir)
    Executes the specified command and arguments in a separate process with the specified environment and working directory.

  12. #12
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Ton problème vient du fait que tu n'est pas sur le même disque...
    CD te change bien le répertoire courant du disque C:, mais tu reste sur le répertoire courant du disque D:...

    Il te faudrait rajouter un C: dans ta commande pour passer sur le disque C: (ou utiliser la méthode exec() avec plusieurs paramètres pour spécifier le répertoire de travail).

    Si tu exécutes la commande cd "C:\video" && dir sur la console depuis le disque D: tu devrais avoir le même résultat...

    Sur mon poste comme je n'ai qu'une seule partition ton code fonctionne très bien... Mais j'aurais quand même quelques remarques :
    • Quand je parle de fermer le flux d'entré, je parle de process.getOutputStream() qui correspond au stdin de la commande. Si tu ne l'utilises pas il est préférable de le fermer car sinon la commande pourrait être bloqué en attente de données qui n'arriveront jamais (mais ce n'est pas le cas avec ta ligne de commande).
    • Il faut traiter les flux dans des threads différents, mais tu n'es pas obligé de créer un thread pour chaque flux : tu peux utiliser le thread courant.
    • Les copies de flux sont très similaire : tu pourrais utiliser une méthode pour cela


    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    public class Main {
     
    	public static void dumpStream(InputStream in, PrintStream out) throws IOException {
    		BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    		String line = "";
    		try {
    			while((line = reader.readLine()) != null) {
    				// Traitement du flux de sortie de l'application si besoin est
    				out.println(line);
    			}
    		} finally {
    			reader.close() ;    
    		}
    	}
     
    	public static void main(String[] args) throws IOException {
     
    		Runtime runtime = Runtime.getRuntime();
    		final Process process = runtime.exec(new String[] { "cmd.exe", "/C", "cd \"C:\\Temp\"" + " && dir" } );
     
    		// On ferme le flux d'entrée du process :
    		process.getOutputStream().close();
     
    		// Consommation du flux d'erreur en arrière plan :
    		new Thread() {
    			public void run() {
    				try {
    					dumpStream(process.getErrorStream(), System.err);
    				} catch(IOException ioe) {
    					ioe.printStackTrace();
    				}
    			}
    		}.start();
     
     
    		//Consommation de la sortie standard de l'application
    		dumpStream(process.getInputStream(), System.out);
    	}
    }
    a++

  13. #13
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Points : 5 778
    Points
    5 778
    Par défaut
    Effectivement le problème viens du fait que tu fait un "cd" vers un répertoire situé sur un autre lecteur.

    Il est possible de spécifier le répertoire directement à la commande dir et ce quelque soit le lecteur courant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new String[] { "cmd.exe", "/C", "dir \"C:\\video\"" }
    Sinon tu peux toujours aller sur le lecteur voulu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new String[] { "cmd.exe", "/C", "C: && cd \"C:\\video\" && dir" }
    [edit] grilled [/edit]

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 67
    Points : 40
    Points
    40
    Par défaut
    Bonjour.

    Sincerement je vous remercie tous.

    C'est bon ca marche. Ton vos conseil ont vraiment été precieux.

    J'ai testé par exemple ce que m'a conseillé le y@m's :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    new String[] { "cmd.exe", "/C", "C: && cd \"C:\\video\" && dir" }
    et ca marche.

    Les conseil que m'a donné adiGuba sur le flux de sortie sont egalement tres interessant.

    Merci a toi aussi LittleBean.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Executer une ligne de commande
    Par Kishikage dans le forum Threads & Processus
    Réponses: 2
    Dernier message: 31/01/2013, 21h42
  2. Réponses: 6
    Dernier message: 12/05/2008, 12h22
  3. executer une ligne de commande
    Par sebgaillard dans le forum Général JavaScript
    Réponses: 18
    Dernier message: 17/04/2008, 18h05
  4. Executer une ligne de commande ET recuperer valeur retour
    Par Korko Fain dans le forum Delphi
    Réponses: 4
    Dernier message: 10/08/2007, 17h31
  5. Réponses: 1
    Dernier message: 27/04/2007, 20h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo