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

Threads & Processus C++ Discussion :

[Vista]Comment attendre la fin d'exécution d'un processus ?


Sujet :

Threads & Processus C++

  1. #1
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut [Vista]Comment attendre la fin d'exécution d'un processus ?
    Bonjour,

    j'aimerais pouvoir créer un processus avec les privilèges administrateurs - ici Install - (jeton complet) à partir d'un processus avec des droits utilisateurs - ici MainProcess - qui attendrait la fin de celui-ci avant de continuer.

    Cela passe evidemment par une élévation de jeton (donc pas possible avec CreateProcess).

    J'ai déjà lu ça. Mais mon programme ne fonctionne pas.

    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
    // MainProcess  [...]
            CString strInstall= str + "\\Install.exe";
     
            SHELLEXECUTEINFO ShellExInfo; 
            ZeroMemory(&ShellExInfo, sizeof(SHELLEXECUTEINFO)); 
            ShellExInfo.cbSize = sizeof( SHELLEXECUTEINFO ); 
     
            ShellExInfo.lpFile = strInstall; 
            ShellExInfo.fMask  = SEE_MASK_NOCLOSEPROCESS; 
            ShellExInfo.lpVerb = _T("open");
            ShellExInfo.nShow  = SW_SHOW ; 
     
            CString strOut = "ShellExecuteEx "+strInstall;
            OutputDebugString(strOut);
            if(ShellExecuteEx(&ShellExInfo)) 
            { 
                OutputDebugString("ShellExecuteEx reussi");
                WaitForSingleObject(ShellExInfo.hProcess, INFINITE);
                CloseHandle(ShellExInfo.hProcess);
            }
            else
            {
                OutputDebugString("ShellExecuteEx echec");
                CloseHandle(ShellExInfo.hProcess); 
                return FALSE;
            }
            /*
            if( ShellExecute(NULL,"open",strInstall,"","",SW_NORMAL ) )
            {
                OutputDebugString("ShellExecute succes ");
            }
            else
            {
                OutputDebugString("ShellExecute echec ");
            }*/
    //[...]
    résultat (Vista) :
    pas de demande d'élévation, un process Install zombie (pas d'affichage, persitance dans liste des processus), le process MainProcess continue (aucune attente)

    en remplaçant ShellExInfo.lpVerb = _T("open"); par ShellExInfo.lpVerb = _T("runas");
    une demande d'élévation, pas de process Install, le process MainProcess continue

    en décommentant la partie ShellExecute
    deux demandes d'élévation, deux process Install, le process MainProcess continue

    en décommentant la partie ShellExecute et en remplaçant ShellExInfo.lpVerb = _T("open"); par ShellExInfo.lpVerb = _T("runas");
    deux demandes d'élévation, deux process Install, le process MainProcess continue

    Il pourrait s'agir d'un problème de droits (un processus utilisiateur ne pouvant "commander" avec un processus administrateur), mais je veux juste attendre sa terminaison ...

    Si quelqu'un à une idée (merci d'avance).

    PS : Vista promet déjà de folles heures d'amusement

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 581
    Points
    41 581
    Par défaut
    Quelle est la valeur retournée par WaitForSingleObject() ?
    Quelle est la valeur de GetLastError() (ou le message obtenu par FormatMessage() à partir de cette valeur) ?

  3. #3
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut
    Désolé de ne pas avoir répondu plus tôt, j'ai été pris par autre chose (et je n'ai plus pu tester sous Vista).

    J'ai mis des OutputDebugString
    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
            CString strInstall= str + "\\Install.exe";
     
            SHELLEXECUTEINFO ShellExInfo; 
            ZeroMemory(&ShellExInfo, sizeof(SHELLEXECUTEINFO)); 
            ShellExInfo.cbSize = sizeof( SHELLEXECUTEINFO ); 
     
            ShellExInfo.lpFile = strInstall; 
            ShellExInfo.fMask  = SEE_MASK_NOCLOSEPROCESS; 
            ShellExInfo.lpVerb = _T("open"); 
            ShellExInfo.nShow  = SW_SHOW ; 
     
            DWORD NumErreur = ERROR_SUCCESS;
            CString str;
            DWORD Taille = 255;
     
            CString strOut = "ShellExecuteEx "+strInstall;
            OutputDebugString(strOut);
            SetLastError( ERROR_SUCCESS );
            if(ShellExecuteEx(&ShellExInfo)) 
            { 
                NumErreur = GetLastError();
                SetLastError( ERROR_SUCCESS );
                FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, NumErreur, 0, str.GetBuffer( Taille ) , Taille , NULL );
                str.ReleaseBuffer();
                str = str + "\n";
                OutputDebugString(str);
     
                OutputDebugString("ShellExecuteEx reussi \n");
                WaitForSingleObject(ShellExInfo.hProcess, INFINITE);
     
                NumErreur = GetLastError();
                SetLastError( ERROR_SUCCESS );
                FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, NumErreur, 0, str.GetBuffer( Taille ) , Taille , NULL );
                str.ReleaseBuffer();
                str = str + "\n";
                OutputDebugString(str);
     
                CloseHandle(ShellExInfo.hProcess);
            }
            else
            {
                OutputDebugString("ShellExecuteEx echec");
                CloseHandle(ShellExInfo.hProcess); 
                return FALSE;
            }
     
            /*
            if( ShellExecute(NULL,"open",strInstall,"","",SW_NORMAL ) )
            {
                OutputDebugString("ShellExecute succes ");
            }
            else
            {
                OutputDebugString("ShellExecute echec ");
            }
            */
     
     
        }
     
        str += "\\Program.exe";
     
        ShellExecute(NULL,"open",str,"","",SW_NORMAL );
    Résultat sous Vista :
    [5356] ShellExecuteEx C:\Users\AdmVista\Desktop\Install.exe
    [5356] Les données nécessaires pour terminer cette opération ne sont pas encore disponibles.
    [5356]
    [5356] ShellExecuteEx reussi
    [5356] Descripteur non valide
    [5356]

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 581
    Points
    41 581
    Par défaut
    Premièrement, vérifie que le handle retourné n'est pas NULL: C'est marqué dans la doc qu'il peut l'être, hélas.

    Ensuite, ne rajoute pas de \n à la fin du message d'erreur: Il y en a déjà un.

    PS: Pour ce genre de choses pointues, je te conseille les forums et les blogs Microsoft...

  5. #5
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut
    Merci pour une réponse aussi rapide

    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
            CString strInstall= str + "\\Install.exe";
     
            SHELLEXECUTEINFO ShellExInfo; 
            ZeroMemory(&ShellExInfo, sizeof(SHELLEXECUTEINFO)); 
            ShellExInfo.cbSize = sizeof( SHELLEXECUTEINFO ); 
     
            ShellExInfo.lpFile = strInstall; 
            ShellExInfo.fMask  = SEE_MASK_NOCLOSEPROCESS; 
            ShellExInfo.lpVerb = _T("open"); 
            ShellExInfo.nShow  = SW_NORMAL ; 
     
            DWORD NumErreur = ERROR_SUCCESS;
            CString str;
            DWORD Taille = 255;
     
            CString strOut = "ShellExecuteEx "+strInstall;
            OutputDebugString(strOut);
            SetLastError( ERROR_SUCCESS );
            if(ShellExecuteEx(&ShellExInfo)) 
            { 
                NumErreur = GetLastError();
                SetLastError( ERROR_SUCCESS );
                FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, NumErreur, 0, str.GetBuffer( Taille ) , Taille , NULL );
                str.ReleaseBuffer();
     
                OutputDebugString(str);
     
                OutputDebugString("ShellExecuteEx reussi \n");
     
                if ( (ShellExInfo.hProcess != NULL ) && ( ShellExInfo.hProcess != INVALID_HANDLE_VALUE) )
                {
     
                    WaitForSingleObject(ShellExInfo.hProcess, INFINITE);
     
                    NumErreur = GetLastError();
                    SetLastError( ERROR_SUCCESS );
                    FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, NumErreur, 0, str.GetBuffer( Taille ) , Taille , NULL );
                    str.ReleaseBuffer();
     
                    OutputDebugString(str);
     
                    CloseHandle(ShellExInfo.hProcess);
                }
                else
                {
                    if  (ShellExInfo.hProcess == NULL )
                    {
                      OutputDebugString("ShellExInfo.hProcess : Handle null \n");            
                    }
                    else
                    {
                        OutputDebugString("ShellExInfo.hProcess : Handle invalide \n");  
                    }
     
                }
            }
            else
            {
                OutputDebugString("ShellExecuteEx echec");
                CloseHandle(ShellExInfo.hProcess); 
                return FALSE;
            }
    [5884] ShellExecuteEx C:\Users\AdmVista\Desktop\Install.exe
    [5884] Les données nécessaires pour terminer cette opération ne sont pas encore disponibles.
    [5884] ShellExecuteEx reussi
    [5884] ShellExInfo.hProcess : Handle null
    Bon je vais continuer à chercher dans les aides MSoft (msdn & co), mais le principe ShellExecuteEx + WaitForSingleObject semble bon (et fonctionner chez d'autres) http://www.helpware.net/VistaCompat.htm (rubrique Programmer Talk) http://www.delphipraxis.net/post722666.html (en Delphi - ne me gène pas - et en Allemand )

    PS : si quelqu'un à le numéro de tel. de Billou

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 581
    Points
    41 581
    Par défaut
    Essaie de faire éxécuter un simple programme t'appartenant (et donc, écrit par toi) avec les droits d'administrateur (demande de sécurité dans le manifest etc.).
    Si ça marche, c'est que le problème venait du programme d'installation. Programme d'installation que ton programme avec les droits d'admin pourra exécuter sans problème.

  7. #7
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut
    Le problème ne vient pas du morceau de code !

    J'ai fait des versions consoles des programmes (le principal, l'installeur, le programme lancé après) toutes simples (juste le morceau de code dans le programme principal) est ça passe. Mieux, il est capable de lancer correctement l'installeur d'origine puis le programme suivant (en ayant attendu) .

    Je vais voir ce qui cloche dans le programme principal (et je ferai un post).

    Merci pour l'aide.

  8. #8
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut
    Voila le code (en plus complet, Boite de Dialogue MFC), fonctionnant :
    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
    BOOL CMainProcessApp::InitInstance()
    {
    	InitCommonControls();
     
    	CWinApp::InitInstance();
     
        /*
    	CMainProcessDlg dlg;
    	m_pMainWnd = &dlg;
    	INT_PTR nResponse = dlg.DoModal();
        */
     
        INT_PTR nResponse = IDOK;
     
        CString str;
        ::GetCurrentDirectory( MAX_PATH ,str.GetBuffer(MAX_PATH));
        str.ReleaseBuffer();
     
        if (nResponse == IDOK)
        {
            CString strInstall= str + "\\Install.exe";
     
            SHELLEXECUTEINFO ShellExInfo; 
            ZeroMemory(&ShellExInfo, sizeof(SHELLEXECUTEINFO)); 
            ShellExInfo.cbSize = sizeof( SHELLEXECUTEINFO ); 
     
            ShellExInfo.lpFile = strInstall; 
            ShellExInfo.fMask  = SEE_MASK_NOCLOSEPROCESS; 
            ShellExInfo.lpVerb = _T("open"); 
            ShellExInfo.nShow  = SW_NORMAL ; 
     
            DWORD NumErreur = ERROR_SUCCESS;
            CString str;
            DWORD Taille = 255;
     
            CString strOut = "ShellExecuteEx "+strInstall;
            OutputDebugString(strOut);
            SetLastError( ERROR_SUCCESS );
            if(ShellExecuteEx(&ShellExInfo)) 
            { 
                NumErreur = GetLastError();
                SetLastError( ERROR_SUCCESS );
                FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, NumErreur, 0, str.GetBuffer( Taille ) , Taille , NULL );
                str.ReleaseBuffer();
     
                OutputDebugString(str);
     
                OutputDebugString("ShellExecuteEx reussi \n");
     
                if ( (ShellExInfo.hProcess != NULL ) && ( ShellExInfo.hProcess != INVALID_HANDLE_VALUE) )
                {
     
                    WaitForSingleObject(ShellExInfo.hProcess, INFINITE);
     
                    NumErreur = GetLastError();
                    SetLastError( ERROR_SUCCESS );
                    FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, NumErreur, 0, str.GetBuffer( Taille ) , Taille , NULL );
                    str.ReleaseBuffer();
     
                    OutputDebugString(str);
     
                    CloseHandle(ShellExInfo.hProcess);
                }
                else
                {
                    if  (ShellExInfo.hProcess == NULL )
                    {
                      OutputDebugString("ShellExInfo.hProcess : Handle null \n");            
                    }
                    else
                    {
                        OutputDebugString("ShellExInfo.hProcess : Handle invalide \n");  
                    }
                }
            }
            else
            {
                OutputDebugString("ShellExecuteEx echec");
                CloseHandle(ShellExInfo.hProcess); 
                return FALSE;
            }  
        }
        str += "\\Program.exe";
     
        ShellExecute(NULL,"open",str,"","",SW_NORMAL );
        return FALSE;
    }
    Décommenter la boîte de dialogue
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CMainProcessDlg dlg;
    	m_pMainWnd = &dlg;
    	INT_PTR nResponse = dlg.DoModal();
    fait revenir le problème. Peut être que lors de sa destruction, il y a quelque chose qui va empêcher Vista de réaliser correctement le ShellExecuteEx (sous Xp ça fonctionne)

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    salut,
    as-tu essaye de passer par CreateProcess ?

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    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 381
    Points : 41 581
    Points
    41 581
    Par défaut
    Si j'ai bien compris la doc, seul ShellExecute() marche avec l'UAC.

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

Discussions similaires

  1. [Process] comment attendre la fin du chargement?
    Par elflamby dans le forum VB.NET
    Réponses: 1
    Dernier message: 03/04/2007, 15h04
  2. [VB.net] Comment attendre la fin d'un programme ?
    Par nakata77 dans le forum VB.NET
    Réponses: 2
    Dernier message: 14/09/2006, 17h16
  3. Attendre la fin d'exécution d'un page en JS
    Par TekP@f dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 26/08/2005, 15h15
  4. [Thread] comment attendre la fin d'un thread?
    Par billynirvana dans le forum Concurrence et multi-thread
    Réponses: 11
    Dernier message: 24/08/2005, 10h43
  5. Comment Attendre la fin d'un Processus
    Par mr_titi dans le forum C++Builder
    Réponses: 3
    Dernier message: 05/06/2003, 16h35

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