Interface en Java qui lance et communique avec un .exe ?

Signaler
Messages postés
17
Date d'inscription
jeudi 6 avril 2006
Statut
Membre
Dernière intervention
18 avril 2006
-
 cs_modigliani -
Bonjour,

je suis en train de faire évoluer un logiciel libre : Surface Evolver. C'est un logiciel appliqué à la chimie simulant des nano-surfaces, qui, une fois lancé, affiche une console MS DOS. On y rentre des commandes pour pouvoir afficher la fenetre de simulation ( fenetre graphique ), ou effectuer des operations sur la surface, entre autres.

Le but de mon travail est d'instaurer une interface qui rend l'utilisation de ce logiciel plus convivial.

Mes QUESTIONS sont :

- Peut-on lancer de JAVA un exécutable ( donc ce logiciel ), et peut-on en intercepter les fenetres pour intégrer (par exemple) la fenetre graphique dans l'interface et pour demander à ce que la console ne soit pas visible ?

- Si oui, comment faire ? ( J'ai essayé avec runtime et exec, ca me met aucune erreur mais ca ne me lance pas le programme).

- Et enfin, peut-on communiquer avec le programme lancé pour que ce soit l'interface qui donne les commandes à la console, et non plus l'utilisateur ?

Je vous remercie infiniement pour vos réponses.

PS : le langage source du logiciel est le C. Si je veux utiliser des fonctions du programme existant, il faudrait que j'utilise la JNI. C'est pourquoi j'essaye de trouver une solution alternative pour éviter de reprendre le code.

32 réponses

Messages postés
492
Date d'inscription
vendredi 30 janvier 2004
Statut
Membre
Dernière intervention
16 mai 2007
9
Salut
Quand tu lances le logiciel et que tu ne recois aucune erreur, c'est possible que ton programme soit lancé : essaie de lui envoyer des commandes comme si tu étais dans la fenetre DOS en utilisant l'outpustream de ton process.

Voila
A++
Messages postés
5350
Date d'inscription
dimanche 4 mai 2003
Statut
Modérateur
Dernière intervention
29 juin 2020
97
Salut,



pour communiquer avec l'applit tu dois récupérer un objet process genre comme ceci



Runtime run = Runtime.getRuntime();

Process process = null;

try {

process = run.exec("uneAppli");

} catch (IOException e) {

e.printStackTrace();

}

/*ou

try {


process = run.exec("uneAppli arg1 arg2 ...");


} catch (IOException e) {


e.printStackTrace();


}

*/

//pour lire stderr

InputStream stdErr = process.getErrorStream();



//pour lire stdout

InputStream stdOut = process.getInputStream();



//pour lui ecrire

OutputStream out = process.getOutputStream();



//pour la killer

process.destroy();



//retour du code de sortie

process.exitValue();




WORA
Messages postés
17
Date d'inscription
jeudi 6 avril 2006
Statut
Membre
Dernière intervention
18 avril 2006

Merci, j'ai essayé ce que vous avez dit, voilà mon code :

Runtime run = Runtime.getRuntime();
Process process = null;
try {
process = run.exec("evolver.exe Cat_plein_asym");
OutputStream out = process.getOutputStream();
out.write((int)'s');
out.write((int)'\n');
}
catch (IOException ioe) {
ioe.printStackTrace();
}

Aucune erreur ne se produit, mais rien ne s'affiche. Et si j'essaie avec un autre programme, genre "notepad.exe", là ça marche. Je me demande si ça ne vient pas du fait que ce soit une console. Mais si jamais le processus etait bien lancé, quand je luis écris 's' et '\n', il devrait m'afficher une fenêtre graphique avec la modélisation de la surface. Et rien ne se passe...

Peut-etre que je ne fais pas tout comme il faut.

Merci de votre réponse.

DIM N.
Messages postés
5350
Date d'inscription
dimanche 4 mai 2003
Statut
Modérateur
Dernière intervention
29 juin 2020
97
Salut,



Essaye de regarder ce qu'il te retourne

WORA
Messages postés
17
Date d'inscription
jeudi 6 avril 2006
Statut
Membre
Dernière intervention
18 avril 2006

Sur la sortie stdErr, il ne me retourne rien.
Quand je fais un print de process.exitValue(), il me dit que le processus n'est pas terminé ( ce qui veut bien dire qu'il est en cours d'exécution ).
Et quand je fais un print de process.toString(), ca me dit:

java.lang.Win32Process@15663a2

Voilà, je pense que le programme s'est lancé, mais qu'il n'affiche pas les fenêtres : avez-vous une solution ?

Merci d'avance.
Messages postés
5350
Date d'inscription
dimanche 4 mai 2003
Statut
Modérateur
Dernière intervention
29 juin 2020
97
Salut,





ba je ne sais pas trop la surtout si avec le note pas ca fonctionne
normalement si l'application permet la saisie en ligne de commande
d'information elle devrait se comporter comme le bloc note.



cependant peux-tu essayer d'afficher stdout avant et après la saisie
d'information. Pour stderr enfaite c'est pas forcé qu'il soit
renseigné, il l'est seulement et seulement si les developpeur ecrive
les erreur dessus ....

WORA
Messages postés
17
Date d'inscription
jeudi 6 avril 2006
Statut
Membre
Dernière intervention
18 avril 2006

quand tu dis "afficher stdout", tu veux dire "System.out.println(System.out)" ?
Messages postés
5350
Date d'inscription
dimanche 4 mai 2003
Statut
Modérateur
Dernière intervention
29 juin 2020
97
Salut,



na je parle de



InputStream stdOut = process.getInputStream();


WORA
Messages postés
5350
Date d'inscription
dimanche 4 mai 2003
Statut
Modérateur
Dernière intervention
29 juin 2020
97
Salut,



na je parle de



InputStream stdOut = process.getInputStream();


WORA
Messages postés
17
Date d'inscription
jeudi 6 avril 2006
Statut
Membre
Dernière intervention
18 avril 2006

Quand je fais ça et que je récupère le flow de données dans un StringBuffer, et que je demande de l'afficher, là il me met un NullPointerException...
Messages postés
5350
Date d'inscription
dimanche 4 mai 2003
Statut
Modérateur
Dernière intervention
29 juin 2020
97
Montre comment tu procède stp

WORA
Messages postés
17
Date d'inscription
jeudi 6 avril 2006
Statut
Membre
Dernière intervention
18 avril 2006

En fait c'est bon, quand je fais afficher le stdout, il s'affiche en fait ce qu'il devrait y avoir sur la console, c'est à dire la présentation du logiciel.
Donc le logiciel est bien lancé : le problème est donc de pouvoir afficher ces fenêtres, ou même mieux pouvoir avoir un contrôle sue celles-ci ( les intercepter en quelque sorte ).

Parceque là, a fortiori, le programme est en route, mais n'affiche rien.

Merci.
Messages postés
17
Date d'inscription
jeudi 6 avril 2006
Statut
Membre
Dernière intervention
18 avril 2006

Voilà mon code :



Runtime run = Runtime.getRuntime();

Process process = null;

int b=0;

int a=0;

String cmd=new String("evolver.exe Cat_plein_asym");



// Lance le programme

try {

process = run.exec(cmd);

}

catch (IOException ioe) {

ioe.printStackTrace();

}



InputStream stdOut = process.getInputStream();



// Affiche stdout

try {

while(a!=4000){

b = stdOut.read();

System.out.print((char) b);

a++;

}

} catch (IOException ex1) {

}



Le problème, c'est qu'il n'affiche pas tout ce qu'il devrait afficher,
il n'affiche que 200 ou 300 caractères, puis il s'arrete. Alors qu'il
est censé en afficher beaucoup plus.

Comme si le programme ne s'était pas lancé entièrement... Bizarre..
Messages postés
5350
Date d'inscription
dimanche 4 mai 2003
Statut
Modérateur
Dernière intervention
29 juin 2020
97
Essaye avec cette classe qui sera plus générique c'est pas
insurmontable comme code donc si tu veux des commentaire dessus tu peux
les rajouter :P



sinon il y a mieux mais bon c'est fais en 5min donc.....





import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;



public class Exec {



private Process process = null;

private InputStream stdOut = null;

private OutputStream stdIn = null;



public Exec(String cmd) {

Runtime run = Runtime.getRuntime();

Process process = null;

//Lance le programme

try {

process = run.exec(cmd);

stdOut = process.getInputStream();

stdIn = process.getOutputStream();

} catch (IOException ioe) {

ioe.printStackTrace();

}

}



public void destroy() {

try {

if (stdOut != null) stdOut.close();

if (stdIn != null) stdIn.close();

} catch (IOException e) {

}

process.destroy();

}



public boolean write(String str) {

try {

stdIn.write(str.getBytes(), 0, str.length());

stdIn.flush();

return true;

} catch (IOException e) {

e.printStackTrace();

return false;

}

}



public boolean writeln(String str) {

return write(str + "\n");

}



public boolean writeln() {

return write("\n");

}



public String read() {

if (stdOut == null) return null;

try {

if (stdOut.available() > 0) {

byte buffer[] = new byte [stdOut.available()];

int n 0, offset 0;

while (true) {

int i = stdOut.available();


n = stdOut.read(buffer, offset,
i);

if (n <0 || n i) {


if (n != -1)
offset += n;

break;

}

offset += n;

}

return new String(buffer, 0, offset);

}

} catch (IOException e) {

e.printStackTrace();

return null;

}

return null;

}

}





a l'utilisation



Exec ex = new Exec("evolver.exe Cat_plein_asym");

System.out.println(ex.read());

System.out.println(ex.writeln("s"));

System.out.println(ex.read());

WORA
Messages postés
17
Date d'inscription
jeudi 6 avril 2006
Statut
Membre
Dernière intervention
18 avril 2006

Désolé, j'ai mis du temps à répondre, j'ai eu un empêchement.



J'ai fait ce que tu m'as dit, et ça me renvoie :



null

true

null



Ca veut dire qu'il n'y rien dans StdOut ?
Messages postés
17
Date d'inscription
jeudi 6 avril 2006
Statut
Membre
Dernière intervention
18 avril 2006

Est-ce qu'il ne faut pas faire communiquer Java et Ms-Dos par Socket ?

N'est-ce pas de cette manière lors d'un "run" que Java récupère la console de sortie?

Si oui, comment puis-je faire ?



Merci.
Messages postés
17
Date d'inscription
jeudi 6 avril 2006
Statut
Membre
Dernière intervention
18 avril 2006

Sinon, par rapport au prog que tu m'as filé, j'ai fait des tests, et
s'il m'affiche "null", c'est parce qu'il ne rentre pas dans le try dans
le read().
Messages postés
17
Date d'inscription
jeudi 6 avril 2006
Statut
Membre
Dernière intervention
18 avril 2006

En fait, il rentre dans le try mais pas dans le if(stdOut.available() > 0).

il renvoie donc le dernier return, c a d null.

En réalité, stdOut n'est pas null, mais le nombre de bits lisible est égal à zéro...
Messages postés
5350
Date d'inscription
dimanche 4 mai 2003
Statut
Modérateur
Dernière intervention
29 juin 2020
97
Salut,



le fait qu'il te renvoi null c'est simplement et qu'il ne rentre pas
dans stdOut.available() donc il n'y a strictement rien a lire



"Est-ce qu'il ne faut pas faire communiquer Java et Ms-Dos par Socket ?"



tu utilise déjà un principe similaire en utilisant l'objet process



apres pour ton teste avec

System.out.println(ex.read()); //null

System.out.println(ex.writeln("s"));//true

System.out.println(ex.read());//null





le premier veut dire qu'il y a un soushi sur la lecture surtout si l'application et sencé t'afficher un pavé de text.
le true veut dire qu'il a qd meme pu lui ecrire le s\n

le troisieme veut dire soit que l'application ne te retourne pas de
confirmation apres une saisie soit qu'il y a tjr le meme prob avec la
lecture






WORA
Messages postés
17
Date d'inscription
jeudi 6 avril 2006
Statut
Membre
Dernière intervention
18 avril 2006

Merci pour tes précisions.



Je peux lancer n'importe quel programme, ça marche.



Mais dès que c'est une console ( même cmd.exe ), ça ne marche plus.

Donc je pense que le problème doit venir du fait que ce soit une console ( invite de commandes).



Si tu as une idée de comment communiquer avec une console, tiens moi au courant.

Sinon, je te remercie pour le temps que tu as passé à m'aider..



A+