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

MFC Discussion :

CreateProcess() communication entre 2 process


Sujet :

MFC

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2014
    Messages : 10
    Points : 11
    Points
    11
    Par défaut CreateProcess() communication entre 2 process
    Bonjour,

    J'utilise CreateProcess() pour lancer un process B à partir d'un process A avec des paramètres et tout se passe bien jusqu'au là.

    Ma question est comment faire pour que le process B envoi au Process A un retour (ex: retourner une chaine de caractère) ? Et comment récupérer ce retour au niveau du process A ?

    PS: Les deux process sont des simples applications de type boites de dialogue.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        WaitForSingleObject(process.hProcess, INFINITE);
        GetExitCodeProcess(process.hProcess, &code);            // 
        //-------> Lire la retour du Process B   
        CloseHandle(process.hThread);
        CloseHandle(process.hProcess);
    Merci à tous

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Divers outils de communication inter-processus: Tubes (possiblement mis à la place de la sortie standard), segments de mémoire partagae (via File Mapping), ou pour les applications fenêtrées, transmission par le message WM_COPYDATA...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2014
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Divers outils de communication inter-processus: Tubes (possiblement mis à la place de la sortie standard), segments de mémoire partagae (via File Mapping), ou pour les applications fenêtrées, transmission par le message WM_COPYDATA...
    Je vous remercie pour la réponse. Sinon j'ai réussi à utiliser la 3ème méthode (WM_COPYDATA) mais j'ai rencontré le pb suivant:

    1 - A partir du processA je lance le processB par un createProcess
    2- Le processB est lancé maintenant, il envoi un message au processA via sendMessage
    3- Le processA ne peut pas traité le retour du processB puisuqe le process B n'est pas encore mort ( WaitForSingleObject ) qui est indispensable pour moi car la tache suivant du processA dépend du retour du ProcessB !

    -------------o----------------
    Sinon la solution qui m'intéresse est la première méthode que tu m'as proposé (les pipes), mais j'arrive pas à réutiliser l'exemple fourni par MSDN https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx
    1- Par quoi je doit remplacer l'utilisation du argv[ ] puisque moi j'utilise des boite de dialogue, je n'ai pas un main (int argc, TCHAR *argv[])
    2- Le processB doit rester en écoute pour récupérer les données envoyé par le processA mais là on sort de la boucle dés la première tentative de lecture si on reçoit rien !!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     for (;;) 
       { 
       // Read from standard input and stop on error or no data.
          bSuccess = ReadFile(hStdin, chBuf, BUFSIZE, &dwRead, NULL); 
     
          if (! bSuccess || dwRead == 0) 
             break;                        //     quitter la boucle si la lecture est échouée  !!!!
     
       // Write to standard output and stop on error.
          bSuccess = WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL); 
     
          if (! bSuccess) 
             break; 
       }

    Si vous avez un exemple plus simple en utilisant des boites de dialogue ça serait super !

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Si tu as un programme fenêtré, alors tu ne devrais pas faire une opération synchrone sur ton thread principal.
    À ta place, je décomposerais ma tâche en étapes, de manière à pouvoir traiter la suite dans un autre message.
    Puis, je mettrais mon WaitForSingleObject() dans un autre thread, qui ferait un PostMessage() une fois le processus terminé!
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2014
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Si tu as un programme fenêtré, alors tu ne devrais pas faire une opération synchrone sur ton thread principal.
    À ta place, je décomposerais ma tâche en étapes, de manière à pouvoir traiter la suite dans un autre message.
    Puis, je mettrais mon WaitForSingleObject() dans un autre thread, qui ferait un PostMessage() une fois le processus terminé!
    Est ce que tu peux me détailler un peu plus ? car je n'arrive pas à implémenter ce que tu m'as suggéré !
    Voici Le code classic en utilisant le message WM_COPYDATA

    Process 3: (OnBnClickedOk())
    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
     
    void Cprocess3Dlg::OnBnClickedOk()
    {
         STARTUPINFO si; 
         PROCESS_INFORMATION pi;
         DWORD code;
         BOOL bRet;
         memset(&si, 0, sizeof(STARTUPINFO));
         si.cb = sizeof(STARTUPINFO); 
     
         bRet = CreateProcess(NULL,   "C:\\Program Files\\projects\\process4\\process4.exe" , NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
     
     
    	 if(!bRet)
    	 {
    		 MessageBox(    "Lancement du process 4 échoué !", "Titre", MB_OK |  MB_ICONERROR);
    	 }
    	 else // lancement réussi  
    	 {
    	      WaitForSingleObject(pi.hProcess,INFINITE);
    	      GetExitCodeProcess(pi.hProcess, &code); 
                  CloseHandle(pi.hThread);
                  CloseHandle(pi.hProcess); 
    	 }
     
     
    //---/  d'autre traitement selon le retour du process 4
     
    //	CDialogEx::OnOK();
     
    }

    Process 3: (OnCopyData())
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    BOOL Cprocess3Dlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
    { 
          CString RxText ;
           RxText = (LPCSTR)(pCopyDataStruct->lpData); 
           AfxMessageBox(m_rxText); 
           return CDialogEx::OnCopyData(pWnd, pCopyDataStruct); 
    }
    Process 4: (OnBnClickedOk())
    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
    void Cprocess4Dlg::OnBnClickedOk()
    {
    	CString		m_thisAppHeader;
    	CString		m_otherAppHeader;	
     LRESULT copyDataResult; 
     
    	CWnd *pOtherWnd = CWnd::FindWindow( NULL ,   "Process3");
    	m_otherAppHeader.ReleaseBuffer(); 
     
    	if (pOtherWnd)
    	{
    		COPYDATASTRUCT cpd;
    		cpd.dwData = 0;
    		CString txt;
    		txt = "ceci est le message de retour envoyé par process B au processA"; // message à envoyer
    		cpd.cbData = txt.GetLength();
    		cpd.lpData = (void*)txt.GetBuffer(txt.GetLength()); 
     
    		 copyDataResult =  pOtherWnd->SendMessage( WM_COPYDATA  , 
                                      		                                 (WPARAM)AfxGetApp()->m_pMainWnd->GetSafeHwnd(), 
    										 (LPARAM)&cpd);
     
    		txt.ReleaseBuffer();
     
         }
     
    	CDialogEx::OnOK();
    }
    //------------/ maintenant pour créer un thread pour intercepter le retour/ la fin du process 4 //-------


    Process 3: (OnBnClickedOk())
    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
     
    void Cprocess3Dlg::OnBnClickedOk()
    {
         STARTUPINFO si; 
         PROCESS_INFORMATION pi;
         DWORD code;
         BOOL bRet;
         memset(&si, 0, sizeof(STARTUPINFO));
         si.cb = sizeof(STARTUPINFO); 
     
         CWinThread* pThread;    //**********
     
         bRet = CreateProcess(NULL,   "C:\\Program Files\\projects\\process4\\process4.exe" , NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
     
     
    	 if(!bRet)
    	 {
    		 MessageBox(    "Lancement du process 4 échoué !", "Titre", MB_OK |  MB_ICONERROR);
    	 }
    	 else // lancement réussi  
    	 {
    	        pThread = AfxBeginThread((AFX_THREADPROC) ThreadReceptionRetourProcss4(&pi ,   &code) ,(LPVOID)this, THREAD_PRIORITY_NORMAL);   //********
                 // WaitForSingleObject(pi.hProcess,INFINITE);
    	     // GetExitCodeProcess(pi.hProcess, &code); 
                 // CloseHandle(pi.hThread);
                 // CloseHandle(pi.hProcess); 
    	 }
     
     
     	CDialogEx::OnOK();
     
    }


    La fonction ThreadReceptionRetourProcss4
    déclaration dans le fichier .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static UINT  ThreadReceptionRetourProcss4( PROCESS_INFORMATION *pi , DWORD *code);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    UINT Cprocess3Dlg::ThreadReceptionRetourProcss4(/*LPVOID param  , */PROCESS_INFORMATION *pi , DWORD *code)     //**********************
    {
             WaitForSingleObject(pi->hProcess,INFINITE);
    	 GetExitCodeProcess(pi->hProcess,  code); 
             CloseHandle(pi->hThread);
             CloseHandle(pi->hProcess); 
    	 return 0;
    }


    Après il faut intercepter le message retourné par le process 4 et arrêter le thread créé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    BOOL bRet;
     
    while( (bRet = GetMessage( &msg, m_hWnd, 0, 0 )) != 0)
    { 
        if (bRet == -1)
        {
            // handle the error and possibly exit
        }
        else
        {
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        }
    }
    sans oublié d'arreter le Thread ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
      DWORD exit_code= NULL;
    if (pThread != NULL)
    {
        GetExitCodeThread(pThread->m_hThread, &exit_code);
        if(exit_code == STILL_ACTIVE)
        {
            ::TerminateThread(pThread->m_hThread, 0);
            CloseHandle(pThread->m_hThread);
        }
        pThread->m_hThread = NULL;
        pThread = NULL;
    }

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Je n'ai pas le temps ou l'énergie de tout analyser en profondeur, mais quelques remarques:
    1. Premier bout de code:
      • Mémorise la PROCESS_INFORMATION quelque part, sans la fermer.
      • Lance un thread en lui donnant ton handle de fenêtre et la PROCESS_INFORMATION
      • Le thread fera juste un WaitForSingleObject() et un PostMessage().
    2. Second bout de code:
      • Évite les AfxMessageBox() pendant ce genre de traitement, ça peut causer des problèmes de MessageBox imbriquées qui saloperont ta pile d'exécution si elles ne sont pas fermées exactement dans le bon ordre. Mémorise les strings dans une CStringList à la place, pour les afficher plus tard.
    3. A l"air OK.
    4. 4e bout de code:
      • Ceci ne marchera pas: (AFX_THREADPROC) ThreadReceptionRetourProcss4(&pi , &code); tu dois faire une fonction (statique) qui prend un void* en paramètre, en réalité une structure (allouée sur le tas, pour que le thread puisse la désallouer à la fin sans souci) avec les données requises (le HWND/CWnd* et la PROCESS_INFORMATION).
    5. La fin:
      • C'est une fenêtre MFC, pour traiter le message il suffit de l'ajouter à ta Message Map; (en tant que ON_MESSAGE(), il me semble) si ça se trouve, les assistants de Visual en sont capables.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Communication entre C++ et C# ou Processing
    Par Gatal168 dans le forum C++
    Réponses: 2
    Dernier message: 19/05/2014, 12h44
  2. Lecture standard et communication entre processus!
    Par Tartar Ukid dans le forum C++Builder
    Réponses: 5
    Dernier message: 05/07/2003, 16h37
  3. Communication entre processus
    Par markopolo dans le forum C++Builder
    Réponses: 2
    Dernier message: 26/06/2003, 16h21
  4. Réponses: 5
    Dernier message: 25/03/2003, 19h43
  5. communication entre programmes
    Par jérôme dans le forum C
    Réponses: 12
    Dernier message: 16/04/2002, 08h05

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