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++ Discussion :

Exécution d'un programme externe


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Points : 101
    Points
    101
    Par défaut Exécution d'un programme externe
    Bonjour,
    Je voudrais depuis un programme C++ sur Windows lancer un programme DOS de façon à ce qu'une fenêtre DOS ne s'ouvre pas à son exécution et récupérer sa sortie standard. Je ne connais que la commande system() mais elle ne répond pas à mes besoins.

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Points : 101
    Points
    101
    Par défaut
    Le processus fils est un outil d'un progiciel, je ne peux pas utiliser ta méthode qui nécessite de développer aussi le fils.

  4. #4
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par DSGSLA Voir le message
    Le processus fils est un outil d'un progiciel, je ne peux pas utiliser ta méthode qui nécessite de développer aussi le fils.
    Non... Il te suffit de créer un pipe dans le processus appelant, puis d'exécuter le processus fils en spécifiant son handle "stdout".

    Points-clé :
    Code Préparation du pipe : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    HANDLE WriteHandle, ReadHandle ;
    SECURITY_ATTRIBUTES SecAttr ;
    SecAttr.nLength=sizeof(SecAttr);
    SecAttr.bInheritHandle=TRUE;
     
    if (!CreatePipe(&ReadHandle, &WriteHandle, &SecAttr, 0))
      // Critical error, exit.
    if (!SetHandleInformation(ReadHandle, HANDLE_FLAG_INHERIT, 0))
      // Critical error, exit.
    Code Flags de création de processus : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    STARTUPINFO Info ;  // Pour CreateProcess
    Info.cb=sizeof(pInfo);
    Info.dwFlags=STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    Info.wShowWindow=SW_HIDE;
    Info.hStdOutput=WriteHandle;
    Code Après le CreateProcess : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CloseHandle(WriteHandle);

    Après, tu n'as plus qu'à lire bourrinement depuis ReadHandle, et ceci jusqu'à fermeture du pipe et/ou fin du processus. N'oublie pas de fermer ReadHandle à la toute fin du traitement, c'est à dire après avoir fermé le handle sur le processus fils qui doit être, normalement, terminé.


    J'ai un code complet gérant ça, mais il est en Delphi et non pas en C++. Ceci étant dit, si tu connais le langage, je peux le poster.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Points : 101
    Points
    101
    Par défaut
    Je ne suis familier qu'avec le C++/STL. Cette méthode évite-elle l'affichage même fugitif de la fenêtre DOS du fils ?

  6. #6
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Oui. C'est le rôle du Info.wShowWindow=SW_HIDE;

    @Mac LAK : c'est CreatePipe(&ReadHandle, &WriteHandle, &SecAttr, 0)

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Points : 101
    Points
    101
    Par défaut
    Je travaille sous dev-C++ et j'essaye de compiler l'exemple du lien donné plus haut. Mais le compilateur ne trouve pas strsafe.h

    De plus dans le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
    c'est chBuf qui reçoit le stdout du processus fils ?

  8. #8
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par Melem Voir le message
    @Mac LAK : c'est CreatePipe(&ReadHandle, &WriteHandle, &SecAttr, 0)
    Arf, copier/coller trop rapide depuis Delphi... Autant pour moi, j'édite le message d'origine.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 198
    Points : 101
    Points
    101
    Par défaut
    Je voulais n'avoir qu'un binaire, mais je plutôt m'orienter vers Qt avec la classe QProcess.
    Merci tout de même de vos interventions.

  10. #10
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Heu... Avec un processus externe non-modifiable, comment veux-tu n'avoir qu'un seul exe ? Tu as forcément le processus père (que tu es en train d'écrire) et le fils (non-modifiable), et il n'y a pas de problème pour la capture de la sortie... Pas franchement pigé ta dernière remarque, là...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  11. #11
    Membre régulier

    Inscrit en
    Décembre 2002
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 49
    Points : 76
    Points
    76
    Par défaut
    quelqu'un a réussi à récupérer la sortie avec ce code ?

    je n'arrive pas à obtenir la sortie avec çà

    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
    	HANDLE WriteHandle, ReadHandle ;
    	SECURITY_ATTRIBUTES SecAttr ;
    	SecAttr.nLength=sizeof(SECURITY_ATTRIBUTES);
    	SecAttr.bInheritHandle=TRUE;
    	SecAttr.lpSecurityDescriptor = NULL; 
     
     
    	if (!CreatePipe(&ReadHandle, &WriteHandle, &SecAttr, 0)){
    		AfxMessageBox("erreur à la creation du pipe");
    		return;
    	}
     
    	if (!SetHandleInformation(ReadHandle, HANDLE_FLAG_INHERIT, 0)){
    		AfxMessageBox("erreur à la creation du handle");
    		return;
    	}
     
    	STARTUPINFO         siStartupInfo;
    	PROCESS_INFORMATION piProcessInfo;
     
    	memset(&siStartupInfo, 0, sizeof(siStartupInfo));
    	memset(&piProcessInfo, 0, sizeof(piProcessInfo));
    	siStartupInfo.cb = sizeof(siStartupInfo);
    	siStartupInfo.dwFlags=STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    	siStartupInfo.wShowWindow=SW_HIDE;
    	siStartupInfo.hStdOutput=WriteHandle;
     
    	/*if(CreateProcess(NULL,,0,0,FALSE,
    						 CREATE_DEFAULT_ERROR_MODE,0,0,                              
    						 &siStartupInfo,&piProcessInfo) == FALSE)
    	{
    	// erreur
    	}*/
     
    	 if( !CreateProcess(NULL, 
          "plink.exe -ssh -l walk41 sfxz03 -pw wi ls",     // command line 
          NULL,          // process security attributes 
          NULL,          // primary thread security attributes 
          TRUE,          // handles are inherited 
          0,             // creation flags 
          NULL,          // use parent's environment 
          NULL,          // use parent's current directory 
          &siStartupInfo,  // STARTUPINFO pointer 
          &piProcessInfo)  // receives PROCESS_INFORMATION
    	 ){
    		 AfxMessageBox("erreur d'exécution");
    		 return;
    	 }
     
     
    	WaitForSingleObject (piProcessInfo.hProcess, INFINITE);
    	CloseHandle (piProcessInfo.hProcess);
    	CloseHandle (piProcessInfo.hThread);
    	CloseHandle(WriteHandle);
     
    	DWORD dwRead, dwWritten; 
    	CHAR chBuf[2048];
    	BOOL bSuccess = FALSE;
    	bSuccess = ReadFile(WriteHandle, chBuf, 2048, &dwRead, NULL);
        AfxMessageBox(chBuf);

Discussions similaires

  1. Exécution d'un programme externe
    Par morofiler dans le forum Langage
    Réponses: 3
    Dernier message: 16/07/2010, 17h29
  2. Réponses: 7
    Dernier message: 03/12/2009, 16h22
  3. [Système] exécution d'un programme externe
    Par wonderyan dans le forum Langage
    Réponses: 2
    Dernier message: 17/09/2007, 12h40
  4. Réponses: 3
    Dernier message: 06/06/2007, 15h19
  5. exécution d'un programme externe
    Par didiss dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 04/04/2007, 12h29

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