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

Windows Discussion :

CreateProcess et ExitProcess


Sujet :

Windows

  1. #1
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut CreateProcess et ExitProcess
    J'aimerais terminer un process cree avec CreateProcess avec ExitProcess et non TerminateProcess.

    ExitProcess termine le process appelant. Comment utiliser dans ExitProcess le HANDLE retourne par CreateProcess ?

    merci

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 369
    Points
    50 369
    Par défaut
    Citation Envoyé par d'Oursse Voir le message
    Comment utiliser dans ExitProcess le HANDLE retourne par CreateProcess ?
    Tu ne peux pas.

    ExitProcess permet au process appelant de SE terminer.
    TerminateProcess permet de terminer un process arbitraire en spécifiant son HANDLE.

    Il faut choisir.

  3. #3
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 588
    Points
    41 588
    Par défaut
    Il y a un moyen, mais c'est crade.
    Mais paradoxalement, moins crade que TerminateProcess().

    Néanmoins, ni l'un ni l'autre ne sont recommandés. La bonne méthode, c'est de dire à l'autre processus de se terminer (par un message Windows ou un autre mécanisme d'IPC).

  4. #4
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut
    2 points me genent:

    * la doc de msdn dit explicitement d'utiliser ExitProcess(). C'est tres bizarre qu'on ne puisse pas l'utiliser
    * dans la mesure ou CreateProcess() peut lancer n'importe quelle application, je ne peux pas savoir comment l'appli se termine (je fais un wrapper autour de CreateProcess, donc la commande qu'on lui passe n'est pas connue a l'avance)

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 588
    Points
    41 588
    Par défaut
    Citation Envoyé par d'Oursse Voir le message
    * la doc de msdn dit explicitement d'utiliser ExitProcess(). C'est tres bizarre qu'on ne puisse pas l'utiliser
    Ben non, c'est pour quitter le processus courant. Elle recommande sans doute que le processus destination utiliser ExitProcess() pour quitter, c'est son droit (même si personnellement je trouve ça sale: Dans le cas idéal, un processus se termine quand tous ses threads se sont terminés, mais de nos jours il y a tellement de fonctions qui créent un thread en arrière-plan que ça n'est plus réaliste, et le code appelle automatiquement ExitProcess() quand la fonction main() retourne).

    * dans la mesure ou CreateProcess() peut lancer n'importe quelle application, je ne peux pas savoir comment l'appli se termine (je fais un wrapper autour de CreateProcess, donc la commande qu'on lui passe n'est pas connue a l'avance)
    Et pourtant, tu autorises à tuer le processus créé? Ben tu ne peux pas avoir le beurre et l'argent du beurre, ni être sâle et propre à la fois. D'un autre côté, tu peux essayer plusieurs méthodes successives, comme le fait le gestionnaire de tâches: Envoyer des messages de fin à ses fenêtres, puis si ça ne marche pas, à son thread principal, puis si ça ne marche toujours pas, tuer le processus...

  6. #6
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut
    le thread principal, c'est celui qui se trouve dans le PROCESS_INFORMATION rempli par CreateProcess ?

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 588
    Points
    41 588
    Par défaut
    Oui.
    Disons que c'est le premier thread créé, et que c'est généralement celui utilisé pour l'interface utilisateur (je pense notamment que ça n'est pas le cas pour les applications Java).

  8. #8
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    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
    C'est surtout que si ce thread principal se termine, ton process se termine également. Donc, les autres threads du processus se font flinguer au passage...
    En règle générale, pour qu'il ne se termine pas sans prévenir, on y met justement la boucle de messages Windows, ça occupe utilement le thread principal justement.

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 588
    Points
    41 588
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    C'est surtout que si ce thread principal se termine, ton process se termine également. Donc, les autres threads du processus se font flinguer au passage...
    Seulement s'il se termine par un retour du main.
    On peut explicitement le terminer avec ExitThread() pour éviter cela, mais ça n'est pas recommandé parce que certains composants du systême (comme COM) peuvent créer des threads sur lesquels tu n'as aucun contrôle, et qui empêchent le processus de se terminer naturellement quand tous les threads "à toi" sont terminés.

    Edit: En bonus, l'article du lendemain. Quand je disais que ExitProcess() était sale...

  10. #10
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    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 Médinoc Voir le message
    Seulement s'il se termine par un retour du main.
    Le thread principal, c'est celui exécutant le main, justement...
    Faudrait essayer pour le fun, mais je doute fortement que flinguer le thread principal (via TerminateThread, tant qu'à faire soyons crades jusqu'au bout) depuis un thread / processus à part permette au processus de continuer à tourner.

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 588
    Points
    41 588
    Par défaut
    Je l'ai déjà fait: Thread principal lance un second thread, second thread fait un truc (comme afficher des messages toutes les secondes pendant dix secondes), premier thread appelle ExitThread() au lieu de sortir du main()...

    PS: Doc à l'appui

  12. #12
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 50
    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
    "ExitThread()", c'est "propre" (enfin... c'est relatif, hein) par rapport à "TerminateThread()"... Enfin, ça reste juste de la curiosité quoi qu'il en soit vu que cela reste du code "crade" si ce n'est pas fait correctement, avec la coopération propre du processus que l'on veut terminer.

  13. #13
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut
    donc pour résumer, j'appelle CreateProcess. Si pi est la structure PROCESS_INFORMATION remplie par CreateProcess, j'appelle CloseHandle sur pi.hProcess (je n'en ai pas besoin). Puis si plus tard je veux arreter l'application lancee par CreateProcess:

    • J'appelle CloseHandle(pi.hThread)
    • Si ca foire, J'appelle TerminateProcess(pi.ProcessId, 0)


    c'est ca ? Notez que j'appelle CloseHandle et pas ExitThread car c'est ce qui est indique dans la doc de CreateProcess

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 197
    Points : 12 349
    Points
    12 349
    Par défaut
    Non.
    Vous demandez au process que vous avez créé de se terminer. Le canal de communication avec le process créé est fonction de celui-ci.

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 588
    Points
    41 588
    Par défaut
    On ne "demande" pas à un programme de se terminer par un TerminateThread() sur son premier thread. Entre autres, c'est une des choses qui laissera tourner les autres threads, puisque le premier thread n'aura pas appelé ExitProcess().

    La méthode que je propose, c'est plus:
    • EnumWindows() + GetWindowThreadProcessId() + PostMessage(WM_CLOSE)
    • et si ça ne marche pas, PostThreadMessage(WM_QUIT)
    • si ça ne marche pas, et si tu en as la volonté, on peut tester plus sournois: CreateRemoteThread(ExitProcess) mais ça a tendance à planter certaines applications, et donc à lancer DrWatson. Étrangement, comme ça prévient les DLLs, je me demande parfois si ça n'est pas plus propre que TerminateProcess()...
    • Quand tout le reste a échoué, TerminateProcess().

    PS: TerminateProcess() nécessite un handle, pas un ID.

  16. #16
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut
    Un code comme ceci pour le callback ?

    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
    static DWORD WINAPI
    _ecore_exe_thread_procedure(LPVOID data)
    {
       ExitProcess(0);
       return 1;
    }
    
    static BOOL CALLBACK
    _ecore_exe_enum_windows_procedure(HWND window, LPARAM data)
    {
       Ecore_Exe *exe;
       DWORD      thread_id;
    
       exe = (Ecore_Exe *)data;
       thread_id = GetWindowThreadProcessId(window, NULL);
       if (thread_id == exe->thread_id)
         {
            if (PostMessage(window, WM_CLOSE, 0, 0))
              return FALSE;
            if (PostThreadMessage(thread_id, WM_QUIT, 0, 0))
              return FALSE;
            if (CreateRemoteThread(exe->process, NULL, 0,
                                   _ecore_exe_thread_procedure, NULL,
                                   0, NULL))
              return FALSE;
         }
    
       return TRUE;
    }
    Je ne suis pas sur si il faut que je passe NULL pour les attributs de securite de CreateRemoteThread.

    Concernant l'utilisation de TerminateProcess(), comme je fais un port Windows d'une bibliotheque Linux et que celle-ci utilise les signaux d'interruption, je ne sais pas s'il faut que je l'utilise tout le temps ou pas. Je demanderai au developpeur principal.

    Au passage, j'ai utilise OpenProcess() apres CreateProcess pour modifier les attributs du processus. Dois-je toujours appeler CloseHandle sur le HANDLE retourne par cette donction ? Ou bien ceci est gerer par certains appels du code ci-dessus ?

    merci en tout cas !

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 588
    Points
    41 588
    Par défaut
    Non, la Callback doit être directement ExitProcess().

    Et normalement, il faudrait regarder où se trouve la fonction dans la DLL (calculer son offset) et où se trouve la DLL dans le processus destination. Mais bon, comme il s'agit de Kernel32, on peut s'en passer (du moins sous XP).

    Note aussi que cette tactique, peut-être même avec le calcul d'offset, peut être invalidée par l'introduction de mécanismes d'ASLR (Address Space Layout Randomization) sous Windows Vista.
    Edit: Apparemment, l'ASLR de Vista ne change que l'emplacement des DLLs en mémoire, donc un calcul d'offset devrait contourner la protection.

  18. #18
    Membre habitué
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 340
    Points : 177
    Points
    177
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Et normalement, il faudrait regarder où se trouve la fonction dans la DLL (calculer son offset) et où se trouve la DLL dans le processus destination. Mais bon, comme il s'agit de Kernel32, on peut s'en passer (du moins sous XP).
    alors, la, je ne sais pas comment faire... D'un cote, je ne fais que le port pour XP, de l'autre, ca m'interesserait d'en savoir plus

  19. #19
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 588
    Points
    41 588
    Par défaut
    Pour calculer l'offset, ceci devrait suffire:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    ptrdiff_t offsetExit = (char const*)GetModuleHandle("kernel32.dll") - (char const*)&ExitProcess;

    Ensuite, il faut trouver la DLL dans l'autre processus. À l'époque, j'avais utilisé CreateToolHelp32Snapshot() et Module32First()/Module32Next(), mais EnumProcessModules() suffit peut-être.

  20. #20
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 197
    Points : 12 349
    Points
    12 349
    Par défaut
    Heu, je veux peut-être dire une connerie mais si la version Linux fait des Kill -9 sur ces fils, il peut faire aussi crade sous Windows.
    Si c'est des signaux USR1 ou USR2, pourquoi ne pas câbler les routines d'interruption sur signal sous Linux dans la pompe à message de la fenêtre principale sur les messages WM_APP et WM_APP+1 ?

    C'est juste pour faire aussi basic que sous Linux.

Discussions similaires

  1. [EXECUTION] CreateProcess / ShellExecute
    Par jmdeffet dans le forum API, COM et SDKs
    Réponses: 2
    Dernier message: 14/10/2004, 11h33
  2. CreateProcess (impossible de gérer le symbole >
    Par borgirz dans le forum Windows
    Réponses: 4
    Dernier message: 03/06/2004, 11h53
  3. [CreateProcess] Comment cacher la fenêtre ?
    Par iubito dans le forum API, COM et SDKs
    Réponses: 5
    Dernier message: 27/04/2004, 19h27
  4. Réponses: 2
    Dernier message: 06/04/2004, 00h06
  5. CreateProcess + paramètres passé
    Par obione dans le forum API, COM et SDKs
    Réponses: 2
    Dernier message: 20/03/2003, 18h25

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