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

C++Builder Discussion :

ShellExecute ou "system(. . .)" ?


Sujet :

C++Builder

  1. #1
    Invité
    Invité(e)
    Par défaut ShellExecute ou "system(. . .)" ?
    Bonjour

    J'ai un exécutable "console" qui s'appelle "Test.exe" et qui prend en paramètre un fichier d'entrée et un fichier de sortie. "Test C:\tmp\toto.bmp C:\tmp\toto.gif" par exemple.
    L'exécutable Test.exe a des instructions "cout" ou "printf" pour indiquer l'avancement de son traitement.
    Et donc si j'exécute en ligne de commande : "Test C:\tmp\toto.bmp C:\tmp\toto.gif > Log.txt", je récupère toutes les sorties "std::cout << " dans le fichier Log.txt.

    Je voudrais exécuter "Test C:\tmp\toto.bmp C:\tmp\toto.gif > Log.txt" à partir d'un programme Win32.

    1) J'ai essayé la commande

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int nRetour = system("\"C:\\dev\\essai\\Test.exe\" C:\\tmp\\toto.bmp C:\\tmp\\toto.gif > Log.txt");
    Et ça fonctionne, sauf que :
    - une grosse fenêtre noire s'ouvre, alors que je ne voudrais pas la voir
    - pour les parametres 1 et 2 (toto.bmp et toto.gif), j'ai une erreur si je les encadre par des guillemets et si je ne met pas de guillements et que j'ai un espace dans un chemin, Test.exe voit 3 parametres au lieu de 2


    2) J'ai essayé la fonction ShellExecute de l'API Win32

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    HINSTANCE hRetour;
      hRetour = ShellExecute(this->Handle,
                             "open",
                             strExe.c_str(),
                             strParametres.c_str(),
                             ExtractFilePath(ParamStr(0)).c_str(),
                             SW_SHOW);
    La commande fonctionne très bien, si je met SW_HIDE à la place de SW_SHOW, je ne vois pas la fenêtre noire, mais...
    ... si je met "a b > out.txt" dans strParametres, le programme "Test.exe" n'interprète pas le ">" comme une redirection et passe 4 paramètres à l'exécutable ("a", "b", ">" et "out.txt") ...

    Vous auriez une idée pour faire un "mix" de ces deux commandes ?
    C'est à dire pouvoir utiliser le redirecteur ">" et en même temps ne plus voir la fenêtre dos noire à l'exécution ?

  2. #2
    Invité
    Invité(e)
    Par défaut _popen
    Apparemment, d'après mes recherches avec Google, il faudrait utiliser "_popen" ...

    Voilà l'exemple qui se trouve dans Builder :

    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
     
    /* this program initiates a child process to run the dir command
       and pipes the directory listing from the child to the parent.
    */
     
    #include <stdio.h>     // popen() pclose() feof() fgets() puts()
    #include <string.h>    // strlen()
     
    int main( ) {
      FILE* handle;        // handle to one end of pipe
      char message[256];   // buffer for text passed through pipe
      int status;          // function return value
     
      // open a pipe to receive text from a process running "DIR"
      handle = _popen("dir /b", "rt");
      if (handle == NULL) {
        perror("_popen error");
      }
     
      // read and display input received from the child process
      while (fgets(message, sizeof(message), handle)) {
        fprintf(stdout, message);
      }
     
      // close the pipe and check the return status
      status = _pclose(handle);
      if (status == -1) {
        perror("_pclose error");
      }
     
      return(0);
    }// main
    Ca devrait me permettre de récupérer les "cout" sans utiliser la redirection dans un fichier.

    J'essaye ça et je vous tiens au courant...

  3. #3
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Kaji
    Apparemment, d'après mes recherches avec Google, il faudrait utiliser "_popen" ...
    C'est bizarre, j'ai utilisé l'exemple de base suivant pour essayer la fonction "_popen" ...

    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
     
      // open a pipe to receive text from a process running "DIR"
      FILE* handle = _popen("dir *.*", "rt");
      if (handle == NULL) {
        std::cout << "Impossible d'ouvrir le fichier" << endl;
        return;
      }
     
      // read and display input received from the child process
      while (fgets(message, sizeof(message), handle)) {
        //ListBox_log->Items->Add(message);
        fprintf(stdout, message);
      }
     
      // close the pipe and check the return status
      int status = _pclose(handle);
      if (status == -1) {
        perror("_pclose error");
      }
    ... et la variable "handle" vaut toujours NULL (erreur).
    Je ne vois pas où est le problème...
    Vous auriez un exemple qui fonctionne ?

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par Kaji
    C'est bizarre, j'ai utilisé l'exemple de base suivant pour essayer la fonction "_popen" ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      // open a pipe to receive text from a process running "DIR"
      FILE* handle = _popen("dir *.*", "rt");
    ... et la variable "handle" vaut toujours NULL (erreur).
    Je ne vois pas où est le problème...
    Vous auriez un exemple qui fonctionne ?

    popen ne fait tout simplement pas l'extension des meta caractères…
    (c'est le rôle de l'interpréteur de commandes de faire cela)
    ensuite il faut aussi donner le chemin complet de l'exécutable : tel qu'écrit popen va chercher "dir" dans le directory courant…
    et évidemment si "dir" est une commande interne de l'interpréteur de commande et non un exécutable à part entière, cela ne fonctionnera pas non plus : il faudrait invoquer l'interpréteur de commande et lui passer "dir" en paramètre…

  5. #5
    Invité
    Invité(e)
    Par défaut _popen ne fonctionne pas pour les programmes fenêtrés
    Bon, voilà, j'ai trouvé ma réponse sur le site de Microsoft :

    C'est normal que _popen ne fonctionne pas dans mon cas...

    Citation Envoyé par Microsoft
    If used in a Windows program, the _popen function returns an invalid file pointer that causes the program to stop responding indefinitely. _popen works properly in a console application. To create a Windows application that redirects input and output, see Creating a Child Process with Redirected Input and Output in the Platform SDK.
    Pour avoir plus d'informations sur le sujet, cliquez ici :
    http://msdn2.microsoft.com/en-us/lib...4b(VS.80).aspx

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 963
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 963
    Par défaut
    Citation Envoyé par Kaji
    Bon, voilà, j'ai trouvé ma réponse sur le site de Microsoft :

    C'est normal que _popen ne fonctionne pas dans mon cas...


    Pour avoir plus d'informations sur le sujet, cliquez ici :
    http://msdn2.microsoft.com/en-us/lib...4b(VS.80).aspx
    si en plus il y a un problème spécifique à Windows…

    mais les remarques concernant qui doit substituer les "*.*" par le contenu approprié du directory courant resteront valables : vous devrez comprendre ce qui se passe et dans quel ordre pour obtenir le résultat souhaité…

  7. #7
    Invité
    Invité(e)
    Par défaut
    J'ai essayé l'exemple de Microsoft avec CreatePipe, CreateProcess, mais si je choisis "CREATE_NO_WINDOW" dans les parametres de CreateProcess, je n'arrive plus à récupérer les sorties de la console...

    Avec la méthode "Pipe", ça fonctionne, je récupère les sorties du programme console dans mon programme Win32, mais obligatoirement avec le terminal affiché...

    Il existe d'autres solutions à tester, je vais bien finir par trouver celle qui me convient...
    Dernière modification par Invité ; 05/03/2007 à 17h37.

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

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