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] Detruire un process lancé par exec()


Sujet :

API standards et tierces Java

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 42
    Points : 37
    Points
    37
    Par défaut [Runtime] Detruire un process lancé par exec()
    Salut,

    Voilà, j'ai un petit souci avec une fonction java. Je dois lancer la visualisation d'une image par l'application par défaut de windows (Paint, ou autre logiciel). Pour cela, j'utilise ce petit bout de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Process proc = Runtime.getRuntime().exec("cmd /c " + urlImage);
    Ca a pour but d'ouvrir le viewer par défaut de windows avec cette image. Jusque là, tout va bien. Le souci arrive quand je veux killer le process que je viens de lancer. A la fin de mon programme, je veux destruire le processus en même temps que mon java

    Du coup, j'utilise la commande destroy

    Mais ca ne detruit pas mon processus, il reste là comme si de rien était

    J'ai fait quelques recherches et il semblerait qu'il y ait un bug dans la fonction destroy de Process.

    Connaissez-vous une solution à mon problème

    Pour info, le programme tourne sous windows 2000 et XP

    merci d'avance

    Séb

  2. #2
    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 Re: [Runtime] Detruire un process lancer par exec()
    Salut,

    Citation Envoyé par Sebounet19
    J'ai fait quelques recherches et il semblerait qu'il y ait un bug dans la fonction destroy de Process.
    On ne pourrait pas avoir plus d'info la dessus ? Un lien ou le détail du bug ?


    Pour moi ce n'est pas un bug de la méthode destroy(), mais c'est lié au comportement du programme "cmd.exe". En effet c'est ce dernier qui lance un nouveau processus...

    Donc l'objet Process de ton application Java est lié au processus "cmd", mais ce dernier se "contente" de créer un nouveau processus ("paint" par exemple) et se termine. Mais ce dernier processus n'est aucunement lié à l'application Java (cmd "casse" le lien) donc c'est normal que tu ne puisses pas le fermer...

    Il faudrait que tu appelles directement la bonne application dans le Runtime.exec()...

    a++

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 42
    Points : 37
    Points
    37
    Par défaut
    Juste pour préciser, si je fait un waitFor(), sur le process, il reste bloqué tant que mon application (paint par exemple) n'est pas fermé. Je me disais donc que le destroy devait aussi agir sur "paint"

    Pour ce qui est de préciser l'application à utiliser, c'est pas envisageable, chaque poste peut utiliser une application différente et surtout, ils n'ont pas les memes config (une pour windows 2000 et une pour XP) donc je ne peux pas passer par là

    Pour l'histoire du processus fils, oui, c'est clair que c'est cmd qui crée un nouveau processus donc j'ai pas forcement la main dessus. Alors est-il possible de récuperer le processus fils ? ou est-il possible d'ouvrir une image sans preciser l'application à utiliser ?

    Pour le lien qui explique un peu le problème, le voici: Forum java sun

    Merci

    Séb

  4. #4
    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
    Citation Envoyé par Sebounet19
    Juste pour préciser, si je fait un waitFor(), sur le process, il reste bloqué tant que mon application (paint par exemple) n'est pas fermé. Je me disais donc que le destroy devait aussi agir sur "paint"
    En effet, le processus "cmd" reste ouvert tant que le processus qu'il crée n'est pas fermé... Mais si tu arrêtes le processus "cmd" il n'arrête pas le processus qu'il a créer... Et cela ne vient vraiment pas de Java, dans le menu "Exécuter" du menu démarrer, il suffit de taper :
    Pour voir qu'il ouvre deux fenêtres (cmd et notepad) et que lorsqu'on ferme "cmd" le bloc-note reste ouvert...

    Citation Envoyé par Sebounet19
    Alors est-il possible de récuperer le processus fils ? ou est-il possible d'ouvrir une image sans preciser l'application à utiliser ?
    Je ne pense pas qu'il soit possible de récupérer le processus fils de "cmd"...
    Sinon pour ouvrir un fichier indépendamment du système tu peux utiliser la méthode Desktop.open() du projet JDIC... C'est plus portable qu'un Runtime.exec("cmd") mais cela ne permet pas d'obtenir d'objet Process (donc cela ne résout pas ton problème puisque tu ne peux pas fermer le processus créé).



    Citation Envoyé par Sebounet19
    Pour le lien qui explique un peu le problème, le voici: Forum java sun
    J'ai regardé un peu la fiche du bug associé, et c'est surtout des problèmes spécifiques à un système/une implémentation... c'est donc difficilement portable (code 16bits windows, parsing de la ligne de commande différente sous Linux/Unix et sous Windows, etc...).

    Ton problème est plus lié au fonctionnement de cmd qui ne ferme pas le processus qu'il a créé lorsque tu le fermes...


    Donc soit tu laisses le processus ouvert lorsque tu arrêtes ton application, soit tu utilises directement le chemin vers l'application à utiliser (en permettant de modifier cela dans la configuration de ton application par exemple).

    a++

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 42
    Points : 37
    Points
    37
    Par défaut
    oki, c'est trés clair en tout cas. Merci pour ton aide.

    Je ne pense pas que mon problème soit résolu mais bon, je vais chercher une autre solution à ça. Je vais faire un petit tour du coté de JDIC

    sinon, une idée qui me passe par la tête. Je ne peux pas ecrire un petit .bat qui me permet de récupérer les processId de l'application que je lance ?

    enfin, ca reste de la grosse bidouille là ...

    Merci

    Séb

  6. #6
    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
    Citation Envoyé par Sebounet19
    sinon, une idée qui me passe par la tête. Je ne peux pas ecrire un petit .bat qui me permet de récupérer les processId de l'application que je lance ?
    Peut-être mais je connais assez mal la gestion des proces de Windows pour t'aider sur ce point...

    Citation Envoyé par Sebounet19
    enfin, ca reste de la grosse bidouille là ...
    Euh... un peu oui

    a++

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 42
    Points : 37
    Points
    37
    Par défaut
    Enfin bon, pour conclure, je dirais que c'est impossible de faire ce que je veux. Y'as plus qu'à trouver une autre solution ...

    Merci encore

    Séb

  8. #8
    Membre chevronné
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Points : 1 996
    Points
    1 996
    Par défaut
    Rien n'est impossible. Il faut prendre le problème par le bon bout.

    Pourquoi ne pas démarrer directement ton processus Paint (mspaint.exe) ?

    Pourquoi désires-tu instancier un shell pour démarrer un processus?

    Un exemple de 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
    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
     
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.StringBufferInputStream;
    import java.util.HashMap;
     
    /*
     * Created on 13.09.2005
     *
     * To change the template for this generated file go to
     * Window>Preferences>Java>Code Generation>Code and Comments
     */
     
    /**
     * @author marfab001
     * 
     * To change the template for this generated type comment go to
     * Window>Preferences>Java>Code Generation>Code and Comments
     */
    public class TestProcess {
     
        private Runtime runtime;
        Process process = null;
        ByteArrayOutputStream error;
     
        public TestProcess() {
           runtime = Runtime.getRuntime();
           error = new ByteArrayOutputStream(1024);
        }
     
        public int execute(String[] args,
                           final OutputStream outStream,
                           final InputStream inpStream,
                           final OutputStream errStream,
                           final long timeout) throws IOException {
        	process = runtime.exec(args, null, null);
     
        	new Thread() {
                public void run() {
                	try {
    					BufferedInputStream errStreamProcess =
    					    new BufferedInputStream(process.getErrorStream());
    					byte[] buffer = new byte[128];
    					int read;
     
    					while ((read = errStreamProcess.read(buffer, 0, buffer.length)) != -1) {
                            if (errStream != null) {
                            	errStream.write(buffer, 0, read);
                            }
    					}
    					errStreamProcess.close();
    				} catch (IOException ioe) {
    					// TODO Auto-generated catch block
    					ioe.printStackTrace();
    				}
                }
        	}.start();
     
     
            new Thread() {
                public void run() {
                    try {
                        BufferedInputStream outStreamProcess =
                            new BufferedInputStream(process.getInputStream());
                        byte[] buffer = new byte[128];
                        int read;
     
                        while ((read = outStreamProcess.read(buffer, 0, buffer.length)) != -1) {
                            if (outStream != null) {
                            	outStream.write(buffer, 0, read);
                            }
                        }
                        outStreamProcess.close();
                    } catch (IOException ioe) {
                        // TODO Auto-generated catch block
                        ioe.printStackTrace();
                    }
                }
            }.start();
     
            if (inpStream != null) {
            new Thread() {
            	public void run() {
            		try {
    					BufferedOutputStream inpStreamProcess = 
    					    new BufferedOutputStream(process.getOutputStream());
    					byte[] buffer = new byte[256];
    					int read;
     
    					while ((read = inpStream.read(buffer, 0, buffer.length)) != -1) {
    					    inpStreamProcess.write(buffer, 0, read);
    					}
    				} catch (IOException ioe) {
    					// TODO Auto-generated catch block
    					ioe.printStackTrace();
    				}
                }
            }.start();
            }
     
            int status = -1;
            if (timeout > 0L) {
              Thread waitFor = new Thread() {
                public void run() {
                    try {
                    	process.waitFor();
                    }
                    catch(InterruptedException ie) {
                    	ie.printStackTrace();
                    }
                }
            };
            waitFor.start();
     
            try {
    			waitFor.join(timeout);
                try {
                	status = process.exitValue();
                }
                catch (IllegalThreadStateException itse) {
                 process.destroy();   
                }
    		} catch (InterruptedException ie) {
    			ie.printStackTrace();
    		}
            }
            else if (timeout == 0L) {
                try {
    				status = process.waitFor();
    			} catch (InterruptedException ie) {
    				// TODO Auto-generated catch block
    				ie.printStackTrace();
    			}
        }
     
            return status;
        }
     
    	public static void main(String[] args) {
           TestProcess process = new TestProcess(); 
           try {
            ByteArrayOutputStream out = new ByteArrayOutputStream(5 * 1024);
            String[] cmd = {"mspaint"};
    		process.execute(cmd, out, null, null, 5000);
            String result = out.toString();
     
            String resultLine[] = result.split(System.getProperty("line.separator"));
            HashMap envMap = new HashMap();
            for (int i = 0; i < resultLine.length; ++i) {
                String env =  resultLine[i];
                int pos = env.indexOf("=");
                if (pos != -1) {
                    String key = env.substring(0, pos);
                    String value = env.substring(pos+1);
                    envMap.put(key, value);
                }
                else {
                    System.out.println(resultLine[i]);
                }
            }
     
    	} catch (IOException ioe) {
    		// TODO Auto-generated catch block
    		ioe.printStackTrace();
    	}
    	}
    }

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 42
    Points : 37
    Points
    37
    Par défaut
    Pourquoi ne pas démarrer directement ton processus Paint (mspaint.exe) ?
    Parce que je veux utiliser le viewer par défaut et non en spécifier un. Je veux que l'utilisateur ouvre l'image en utilisant son outil préféré

    Pourquoi désires-tu instancier un shell pour démarrer un processus?
    C'est la seule solution que j'ai trouvé pour ouvrir directement une image dans le viewer par défaut

    si je met juste le nom de l'image dans le exec, cela ne fonctionne pas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Runtime.getRunTime().exec("image.tif");
    Un exemple de code
    euh, c'est quoi le principe ?

    ++

    Séb

  10. #10
    Membre chevronné
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Points : 1 996
    Points
    1 996
    Par défaut
    J'avai mal lu l'énoncé de ton problème. Mon code permet de lancer une application (avec ou sans timeout).


    Mais bon, c'est possible mais un peu plus long.

    Cette solution n'a été testée que sous Windows XP Pro.

    Le principe est de récupérer le nom de l'application lié à une extension:

    - On récupère l'extension du fichier
    image.gif ==> .gif
    - On lance la commande 'assoc' avec comme paramètre l'extension du fichier pour récupérer le type de fichier associé: assoc .gif
    => .gif=giffile
    - On lance la commande 'ftype' avec comme paramètre le type de fichier pour récupérer l'application: ftype giffile
    =>giffile="C:\Programme\Gemeinsame Dateien\Microsoft Shared\PhotoEd\PHOTOED.EXE" "%1"

    C'est un plus difficile pour l'application.

    EDIT: Il existe peut être une possibilité plus directe mais je ne la connais pas.

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 42
    Points : 37
    Points
    37
    Par défaut
    C'est avec JDIC que tu fais ça.

    Bon, je vais me plonger dans JDIC car la solution que tu proposes semble me convenir

    merci

    Séb

  12. #12
    Membre chevronné
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Points : 1 996
    Points
    1 996
    Par défaut
    Non, je n'utilise pas JDIC.
    C'est sûrement une bonne solution

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 42
    Points : 37
    Points
    37
    Par défaut
    Qu'utilises-tu alors pour faire ça ?

    Séb

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 42
    Points : 37
    Points
    37
    Par défaut
    Salut,

    En utilisant ta solution Jowo, ca fonctionne trés bien.

    1) Je récupére l'application utilisée par les fichiers d'une extension (avec jdic)
    2) Je recherche ma méthode d'ouverture du fichier
    3) Je remplace le %1 par mon nom de fichier
    4) Je kill le process si il y en déjà un en cours
    5) Je démarre le process

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    AssociationService assocService = new AssociationService();
    Association assoc = new Association();
    assoc = assocService.getFileExtensionAssociation(".tif");
    Iterator iter = assoc.getActionList().iterator();
    while (iter.hasNext()) {
      org.jdesktop.jdic.filetypes.Action item = (org.jdesktop.jdic.filetypes.Action)iter.next();
      if(item.getVerb().equals("Open")) {
        String cmd = item.getCommand().replaceAll("%1","c:\\\\temp\\\\facture.tif");
        if(proc != null)
          proc.destroy();
        proc = Runtime.getRuntime().exec(cmd);
        break;
      }
    }
    Ca me permet d'ouvrir une appli windows en 1 seul exemplaire tout au long de la vie de mon java

    Merci pour tous ces conseils

    Séb

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

Discussions similaires

  1. [Débutant] Comment attendre la fin d'un process lancé par ShellExecute ou ShellExecuteEx
    Par Godzestla dans le forum C++Builder
    Réponses: 3
    Dernier message: 19/05/2011, 12h34
  2. Réponses: 6
    Dernier message: 28/01/2008, 14h01
  3. Connaitre PID d'un process lancé avec exec()
    Par hugo123 dans le forum Langage
    Réponses: 4
    Dernier message: 02/06/2006, 14h28
  4. Transmettre des commandes à un process lancé par ksh
    Par jojolepabo dans le forum Linux
    Réponses: 3
    Dernier message: 19/10/2005, 16h05
  5. [Process] comment savoir si exec est termine
    Par v1nc3kr0 dans le forum API standards et tierces
    Réponses: 6
    Dernier message: 29/06/2005, 16h54

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