Exécuter des sous-processus arbitraires sous Windows et toujours se terminer proprement?

J’ai une application A que j’aimerais pouvoir invoquer d’autres processus arbitraires tels que spécifiés par un utilisateur dans un fichier de configuration.

Le script B est l’un des processus qu’un utilisateur souhaite être appelé par A. B configure certaines variables d’environnement, affiche des messages et appelle un compilateur C pour effectuer certaines tâches.

Windows fournit-il un moyen standard de terminer proprement les processus arbitraires? Supposons que A est exécuté dans une console et reçoit un CTRL + C. Peut-il transmettre cela à B et C? Supposons que A s’exécute dans une fenêtre et que l’utilisateur tente de fermer la fenêtre, peut-il annuler B et C?

TerminateProcess est une option, mais pas une très bonne. Si A utilise TerminateProcess sur B, C continue de fonctionner. Cela pourrait causer des problèmes désagréables si C fonctionne depuis longtemps, car nous pourrions démarrer une autre instance de C pour opérer sur les mêmes fichiers alors que la première instance de C est encore secrètement au travail. De plus, TerminateProcess n’aboutit pas à une sortie propre.

GenerateConsoleCtrlEvent semble agréable et peut fonctionner lorsque tout fonctionne dans une console, mais la documentation indique que vous ne pouvez envoyer CTRL + C que sur votre propre console, ce qui ne vous serait d’aucune aide si A s’exécutait dans une fenêtre.

Y a-t-il un équivalent à SIGINT sous Windows? J’aimerais trouver un article comme celui-ci: http://www.cons.org/cracauer/sigint.html pour Windows.

    Je suppose que je suis un peu en retard sur cette question mais je vais écrire quelque chose pour quiconque a le même problème.

    Mon problème est similaire en ce que je souhaite que mon application soit une application graphique mais que les processus exécutés soient exécutés en arrière-plan sans aucune fenêtre de console interactive connectée.

    J’ai réussi à résoudre ce problème en utilisant GenerateConsoleCtrlEvent (). La partie la plus délicate est que la documentation n’est pas vraiment claire sur la manière dont elle peut être utilisée et sur les pièges.

    Ma solution est basée sur ce qui est décrit ici . Mais cela n’expliquait pas vraiment tous les détails non plus, alors voici les détails sur la manière de le faire fonctionner.

    1. Créez une nouvelle application d’assistance “Helper.exe”. Cette application sera située entre votre application (parent) et le processus enfant que vous souhaitez pouvoir fermer. Il créera également le processus enfant réel. Vous devez avoir ce processus “intermédiaire” ou GenerateConsoleCtrlEvent () échouera.

    2. Utilisez une sorte de mécanisme IPC pour communiquer du parent au processus d’assistance que l’aide doit fermer le processus enfant. Lorsque l’assistant obtient cet événement, il appelle “GenerateConsoleCtrlEvent (CTRL_BREAK, 0)” qui se ferme et le processus fils. J’ai utilisé un object événement pour cela moi-même que le parent termine lorsqu’il veut annuler le processus enfant.

    Pour créer votre fichier Helper.exe, créez-le avec CREATE_NO_WINDOW et CREATE_NEW_PROCESS_GROUP. Et lorsque vous créez le processus enfant, créez-le sans indicateur (0), ce qui signifie qu’il dérive la console de son parent. Ne pas le faire le fera ignorer l’événement.

    Il est très important que chaque étape se déroule comme ceci. J’ai essayé toutes sortes de combinaisons, mais cette combinaison est la seule qui fonctionne. Vous ne pouvez pas envoyer un événement CTRL_C. Il renverra le succès mais sera ignoré par le processus. CTRL_BREAK est le seul qui fonctionne. Cela n’a pas vraiment d’importance puisqu’ils appelleront tous deux ExitProcess () à la fin.

    Vous ne pouvez pas non plus appeler GenerateConsoleCtrlEvent () avec un identifiant de groupe de processus de l’ID de processus enfant permettant directement au processus d’assistance de continuer à vivre. Cela échouera aussi.

    J’ai passé une journée entière à essayer de faire fonctionner ce système. Cette solution fonctionne pour moi, mais si quelqu’un a quelque chose à append, faites-le. Je suis allé tous les autres sur le net en trouvant beaucoup de personnes avec des problèmes similaires, mais aucune solution définitive au problème. Le fonctionnement de GenerateConsoleCtrlEvent () est également un peu bizarre, donc si vous connaissez plus de détails, partagez-le.

    Comme @Shakta a dit que GenerateConsoleCtrlEvent() est très compliqué, vous pouvez envoyer Ctrl + C sans processus d’assistance.

     void SendControlC(int pid) { AttachConsole(pid); // attach to process console SetConsoleCtrlHandler(NULL, TRUE); // disable Control+C handling for our app GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0); // generate Control+C event }