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

Langage Delphi Discussion :

Extermination de process.


Sujet :

Langage Delphi

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juillet 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juillet 2008
    Messages : 71
    Points : 32
    Points
    32
    Par défaut Extermination de process.
    Bonjour tout le monde,

    Je rencontre actuellement un problème pour la suppression de processus.
    Je serai donc fort intéressé par un petit coup de main.

    Le but étant de supprimer tous les processus fils d'un processus que j'ai lancé.Ctrl-C dans la console fait çà très bien mais la console n'est pas forcement affichée et je veux que la suppression se passe par un simple clic sur un bouton.

    A la base je suis parti sur un CreateProcess tué par un Terminateprocess mais cela ne supprime que le processus père.
    J'ai donc changé de stratégie. je crée un process avec createprocess+le flag CREATE_NEW_PROCESS_GROUP pour que tous les process fils appartiennent au mem groupe. Ensuite pour supprimer tout ça, je fais une GenerateConsoleCtrlEvent (CTRL_C_EVENT ou CTRL_BREAK_EVENT) sur le ProcessId du père. En toute logique, le process père et tous ses fils devraient etre tués, non? Aprés la commande, toute la petite bande de processus est toujours là....même le pere. Je comprend pas pourquoi.

    Voici les deux fct utilisées:
    -CreateProcess(nil,cmd,nil,nil,false,0, nil, nil, startinfo, proc_info)
    -GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,proc_info.dwProcessId);

    Une idée?

    Merci d'avance.

  2. #2
    Nouveau membre du Club
    Inscrit en
    Juillet 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juillet 2008
    Messages : 71
    Points : 32
    Points
    32
    Par défaut
    Salut,
    pour info, un SysErrorMessage (GetLastError) aprés mon GenerateConsoleCtrlEvent, me retourne "Descripteur non valide"

    Une idée?

  3. #3
    Nouveau membre du Club
    Inscrit en
    Juillet 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juillet 2008
    Messages : 71
    Points : 32
    Points
    32
    Par défaut
    bon ben finalement, j'ai developpé une fonction qui tue un par un le processus et tous ses descendants. La voici:

    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
     
     
    procedure killAllProcessesFrom(procId : DWORD);
    var
      SnapShot: Cardinal;
      ProcessEntry: TProcessEntry32;
      processhandle : thandle;
    begin
      //Création de "l'instantané"
      SnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     
      //En cas d'erreur on sort
      If SnapShot = 0 then Exit;
     
      ProcessEntry.dwSize := SizeOf(ProcessEntry);
     
      //On liste les processus
      If Process32First(SnapShot, ProcessEntry) then
      begin
        Repeat
     
        //si le processus courant est le parent, on descend dans l'arbre
        if ProcessEntry.th32ParentProcessID = procId
        then killAllProcessesFrom(ProcessEntry.th32ProcessID)
     
        until not Process32Next(SnapShot, ProcessEntry)
      end;
     
      //Libération de l'instantané
      CloseHandle(SnapShot);
     
      //Suppression du process courant
      processhandle := openprocess(PROCESS_TERMINATE, FALSE, procID);
      terminateprocess(processhandle, 4);
    End;

  4. #4
    Nouveau membre du Club
    Inscrit en
    Juillet 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juillet 2008
    Messages : 71
    Points : 32
    Points
    32
    Par défaut
    Il arrive que cette fonction me produise un gros crash... (écran bleu).
    C'est très rare mais ça arrive! Probablement dut à ce qui peut se passer entre le moment où je fais le snapshot et le moment où les processus sont supprimés. Est-il possible qu'entre temps, un des processus fils ce soit terminé et qu'un autre processus (par exemple un processus système) ait récupéré le même ID?

    Je suis donc de nouveau à la recherche d'une méthode pour tuer un processus et tous ces fils si celui-ci en a lancé. N'existe-t-il pas dans l'api windows quelque chose pour faire ça?

  5. #5
    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 user8 Voir le message
    Il arrive que cette fonction me produise un gros crash... (écran bleu).
    Ce qui est assez normal en soi : ta fonction est récursive, et tue donc tous les processus enfants d'un process...
    Maintenant, quand tu as tué tous les fils d'un sous-processus A, par exemple, n'as-tu pas l'impression que dans le snapshot toujours en mémoire, les descendants du processus A déjà tué sont toujours là ?

    Remplace ton appel récursif par un TerminateProcess, et cela devrait aller bien mieux.

    Citation Envoyé par user8 Voir le message
    Est-il possible qu'entre temps, un des processus fils ce soit terminé et qu'un autre processus (par exemple un processus système) ait récupéré le même ID?
    Possible, mais peu probable... Je dirais plutôt que tu ne contrôles pas assez tes erreurs lors de l'appel récursif, d'où crash, vu que tu utilises un snapshot "vieux" lors de tes flinguages de processus.

    La bonne méthode, c'est de récupérer la liste des PID à tuer, puis de les tuer. Les tuer pendant l'énumération n'est pas spécialement une bonne idée en soi.

  6. #6
    Nouveau membre du Club
    Inscrit en
    Juillet 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juillet 2008
    Messages : 71
    Points : 32
    Points
    32
    Par défaut
    A chaque appel de ma fonction, un snapshot est créé. ce snapshot me permet juste de récupérer les ID des proc fils. On appel la fonction avec ces IDs. Une fois que tous les fils sont passés dans la moulinette on supprime le pere. Ce qui me permet, par recurence, de killer toute l'arborescence. Si je remplace mon appel par un terminate process, les fils du premier niveau seront tués mais pas les descendants. Au moment ou je tue le pere, peu importe que le snapshot contienne les fils qui ont été tué. le snapshot permet juste a un niveau n d'appeler les fils n+1...


    La bonne méthode, c'est de récupérer la liste des PID à tuer, puis de les tuer.
    Recursivement, c'est ce que je fais!

    Les tuer pendant l'énumération n'est pas spécialement une bonne idée en soi.
    Le pere est tué aprés que tous les appels des fils aient été fait. Donc au final, je fait tous les appels jusqu'au dernier niveau puis on tue tous les proc appelés depuis le dernier niveau jusqu'au 1 ancetre. Au final, il est juste possible qu'on veuille tué un process qui s'est terminé. Si l'ID n'est pas reattribué, pas de souci terminate process fait rien mais si il a été ré-attribué... gros problème. D'où ma derniere question de mon dernier message.

    Possible, mais peu probable...
    En 1 an, l'ecran bleu s'est produit 3 fois!

  7. #7
    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 user8 Voir le message
    A chaque appel de ma fonction, un snapshot est créé. ce snapshot me permet juste de récupérer les ID des proc fils.
    Sauf que au moment où tu les as tués, ces fils, tu as toujours un snapshot dans la fonction appelante qui contient potentiellement des PID invalides !!.

    Citation Envoyé par user8 Voir le message
    Au moment ou je tue le pere, peu importe que le snapshot contienne les fils qui ont été tué. le snapshot permet juste a un niveau n d'appeler les fils n+1...
    C'est pendant la boucle du père, le problème...

    Citation Envoyé par user8 Voir le message
    Recursivement, c'est ce que je fais!
    Oui, mais pas avec la bonne fonction...

    Citation Envoyé par user8 Voir le message
    Au final, il est juste possible qu'on veuille tué un process qui s'est terminé. Si l'ID n'est pas reattribué, pas de souci terminate process fait rien mais si il a été ré-attribué... gros problème. D'où ma derniere question de mon dernier message.
    Et d'où ma réponse : change ta fonction, et fais ainsi :
    • Récursion, via snapshot, et récupération intégrale de la liste des PID enfant.
    • Retourne les PID via des tableaux dynamiques par exemple, ou ajoutes-les à une liste passée par le père. On s'en fout, l'essentiel, c'est qu'elle ne contienne aucun doublon.
    • Une fois la récursion terminée, passe en revue tous les PID fils, tue-les, et essaie si possible de terminer proprement le père (TerminateProcess sur le processus courant, c'est mal...).
    C'est plus clair ainsi ?

  8. #8
    Nouveau membre du Club
    Inscrit en
    Juillet 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juillet 2008
    Messages : 71
    Points : 32
    Points
    32
    Par défaut
    oui plus clair.

    encore merci

  9. #9
    Nouveau membre du Club
    Inscrit en
    Juillet 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Juillet 2008
    Messages : 71
    Points : 32
    Points
    32
    Par défaut
    Le process ancêtre est lancé depuis un createprocess. A partir de la, n'y a t il pas de solution plus simple pour tuer tous les descendants? En utilisant la fenêtre? L'environnement?

    Personne n'a jamais été confronté à ce problème?

Discussions similaires

  1. Coment faire du post-processing avec Dx9 ?
    Par rolkA dans le forum DirectX
    Réponses: 23
    Dernier message: 24/11/2003, 21h15
  2. Nom d'un process!!!
    Par Oswald dans le forum C
    Réponses: 12
    Dernier message: 01/09/2003, 15h49
  3. Gestion des process
    Par Oswald dans le forum C
    Réponses: 3
    Dernier message: 29/08/2003, 11h52
  4. Réponses: 4
    Dernier message: 01/07/2003, 15h47
  5. [DOM] Ajout d'une instrution de processing
    Par corwin_d_ambre dans le forum Format d'échange (XML, JSON...)
    Réponses: 9
    Dernier message: 06/05/2003, 11h51

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