Puis-je envoyer un ctrl-C (SIGINT) pour une application sur Windows?
J'ai (dans le passé) écrit de la croix-plateforme (Windows/Unix) applications qui, lorsqu'il est démarré à partir de la ligne de commande, gérée tapé par l'utilisateur Ctrl-C combinaison de la même façon (c'est à dire à mettre fin à l'application proprement).
Est-il possible sur Windows pour envoyer une Ctrl-C/SIGINT/équivalent à un processus à partir d'un autre (sans relation) le processus de demande de qui il mettre fin à proprement (lui donnant la possibilité de ranger des ressources, etc.)?
- J'ai été intéressé par l'envoi de Ctrl-C pour java processus de service juste pour obtenir threaddumps. Il semble que
jstack
fiable peut être utilisé à la place de cette question: stackoverflow.com/a/47723393/603516 - docs.microsoft.com/en-us/windows/console/...
Vous devez vous connecter pour publier un commentaire.
La plus proche que je suis arrivé à une solution, est la SendSignal 3ème partie de l'app. L'auteur liste de code source et un fichier exécutable. J'ai vérifié qu'il fonctionne sous windows 64 bits (comme un programme 32 bits, tuant un autre programme 32 bits), mais j'ai pas trouvé comment intégrer le code dans un programme windows (32 bits ou 64 bits).
Comment cela fonctionne:
(Faire précéder de
start
si en cours d'exécution dans un fichier de commandes.)J'ai fait quelques recherches autour de ce thème, qui s'est avéré être plus populaire que ce que je pensais. KindDragon la réponse a été l'un des points cardinaux.
J'ai écrit un plus blog post sur le sujet et créé un programme de démonstration qui illustre l'utilisation de ce type de système pour fermer une application en ligne de commande dans un couple de nice de la mode. Ce poste également des listes de liens externes que j'ai utilisé dans mes recherches.
En bref, ces programmes de démonstration procédez de la manière suivante:
Edit: la version modifiée de La solution de KindDragon pour ceux qui sont intéressés dans le code ici et maintenant. Si vous envisagez de démarrer d'autres programmes après l'arrêt de la première, vous devez le réactiver les touches Ctrl-C de la manipulation, sinon, le processus suivant sera hériter du parent état désactivé et ne permettra pas de répondre à Ctrl-C.
Aussi, un plan d'urgence de la solution si
AttachConsole()
ou l'envoyé de signal de panne, par exemple, dormir puis ceci:wait()
j'ai enlevé le Re-activer Ctrl-C (SetConsoleCtrlHandler(null, false);
). J'ai fait quelques tests (plusieurs appels,également sur déjà terminé les processus) et je n'ai pas trouvé d'effets secondaires (pas encore?).Je suppose que je suis un peu en retard sur cette question, mais je vais écrire quelque chose quand même pour quelqu'un ayant le même problème.
C'est la même réponse que j'ai donné à cette question.
Mon problème est que j'aimerais que ma demande soit d'une application graphique, mais le processus exécuté doit être exécuté en arrière-plan sans aucune console interactive de la fenêtre ci-joint. Je pense que cette solution devrait également fonctionner lorsque le processus parent est un processus de console. Vous pouvez avoir à supprimer le "CREATE_NO_WINDOW" drapeau si.
J'ai réussi à résoudre ce à l'aide de GenerateConsoleCtrlEvent() avec une application de wrapper. La partie la plus délicate est juste que la documentation n'est pas vraiment clair sur exactement comment il peut être utilisé et les pièges avec elle.
Ma solution est basée sur ce qui est décrit ici. Mais cela n'a pas vraiment l'expliquer tous les détails et avec une erreur, voici donc les détails sur la façon d'obtenir ce travail.
Créer une nouvelle application d'aide "Helper.exe". Cette application va s'asseoir entre votre application (parent) et le processus de l'enfant que vous voulez être en mesure de fermer. Il permettra aussi de créer de réels processus enfant. Vous devez avoir cet "homme du milieu" ou GenerateConsoleCtrlEvent() échouera.
Utiliser une sorte de mécanisme IPC de communiquer de la part du parent à l'aide de processus que l'aide doit fermer le processus de l'enfant. Lorsque l'assistant d'obtenir cet événement qu'il appelle "GenerateConsoleCtrlEvent(CTRL_BREAK, 0)", qui se ferme de lui-même et le processus de l'enfant. J'ai utilisé un objet d'événement de ce moi-même qui le parent se termine quand il veut annuler le processus de l'enfant.
Pour créer votre Helper.exe créer avec CREATE_NO_WINDOW et CREATE_NEW_PROCESS_GROUP. Et lors de la création de l'enfant à créer avec pas de drapeaux (0) signifie qu'elle va tirer la console de son parent. Sinon, cela va l'amener à ignorer l'événement.
Il est très important que chaque étape se fait de cette manière. J'ai essayé toutes sortes de combinaisons, mais cette combinaison est le seul qui fonctionne. Vous ne pouvez pas envoyer un CTRL_C événement. Il sera de retour le succès, mais sera ignoré par le processus. CTRL_BREAK est le seul qui fonctionne. N'a pas vraiment d'importance, parce qu'ils seront tous deux appel ExitProcess() à la fin.
Vous aussi vous ne pouvez pas appeler GenerateConsoleCtrlEvent() avec un processus de groupd id de l'enfant id de processus directement permettant l'aide du processus de continuer à vivre. Cela ne fonctionne pas ainsi.
J'ai passé une journée entière à essayer d'obtenir ce travail. Cette solution fonctionne pour moi, mais si quelqu'un a quelque chose à ajouter s'il vous plaît. Je suis allé sur le net de trouver beaucoup de gens avec des problèmes similaires, mais pas de solution définitive au problème. Comment GenerateConsoleCtrlEvent() fonctionne est un peu bizarre donc si quelqu'un en sait plus de détails sur le s'il vous plaît partager.
Edit:
Pour une GUI Application, la façon "normale" pour répondre à ces questions de développement Windows serait d'envoyer un message WM_CLOSE pour le processus de la fenêtre principale.
Pour une application console, vous devez utiliser SetConsoleCtrlHandler pour ajouter un
CTRL_C_EVENT
.Si la demande ne respecte pas, que, vous pouvez l'appeler TerminateProcess.
En quelque sorte
GenerateConsoleCtrlEvent()
retour d'erreur si vous l'appelez pour un autre processus, mais vous pouvez la joindre à une autre application de console et d'envoyer l'événement à tous les processus enfants.Voici le code que j'utilise dans mon C++ app.
Points positifs :
Points négatifs :
Exemple d'utilisation :
Il doit être clairement explicité car pour l'instant il ne l'est pas.
Il est modifié et la version compilée de SendSignal pour envoyer Ctrl-C (par défaut, il n'envoie Ctrl+Pause). Voici quelques binaires:
J'ai également mis les fichiers au cas où:
Version 32 bits: https://www.dropbox.com/s/r96jxglhkm4sjz2/SendSignalCtrlC.exe?dl=0
Version 64 bits: https://www.dropbox.com/s/hhe0io7mcgcle1c/SendSignalCtrlC64.exe?dl=0
Avertissement: je n'ai pas construit ces fichiers. Aucune modification n'a été faite à la compilation
les fichiers originaux. La seule plate-forme testée est la version 64-bit de Windows 7. Il est recommandé d'adapter le code source est disponible à http://www.latenighthacking.com/projects/2003/sendSignal/ et le compiler vous-même.
En Java, en utilisant la JNA avec l'Kernel32.dll bibliothèque, semblable à un C++ solution. Exécute le CtrlCSender méthode main comme un Processus qui obtient juste la console du processus pour envoyer la combinaison de touches Ctrl+C événement et génère l'événement. Comme il fonctionne séparément, sans console Ctrl+C l'événement n'a pas besoin d'être désactivé et activé à nouveau.
CtrlCSender.java - Basé sur Nemo1024 de l' et KindDragon de l' réponses.
Donné un procédé connu ID, ce consoless application, vous fixez la console de processus ciblées et de générer un CTRL+C Événement sur elle.
Principale de l'Application des Pistes de CtrlCSender séparément consoless processus
Un de mes amis a suggéré une complète autre façon de résoudre le problème et il a travaillé pour moi. L'utilisation d'un script vbscript comme ci-dessous. Il commence et l'application, le laisser fonctionner pendant 7 secondes et fermer à l'aide de ctrl+c.
'Exemple VBScript
Basé sur l'id du processus, nous pouvons envoyer le signal à la fin du processus avec force ou avec élégance ou tout autre signal.
Liste de tous les processus :
De tuer le processus:
Détails:
http://tweaks.com/windows/39559/kill-processes-from-command-prompt/
Je trouve tout cela trop compliqué et utilisé SendKeys pour envoyer un CTRL-C frappe à la fenêtre de ligne de commande (c'est à dire cmd.exe de la fenêtre) comme une solution de contournement.
Oui. Le
windows-kill
projet est exactement ce que vous voulez: