Ich denke, ich bin etwas spät dran, aber ich werde trotzdem etwas für jeden schreiben, der das gleiche Problem hat. Dies ist die gleiche Antwort, die ich auf diese Frage gegeben habe.
Mein Problem war, dass meine Anwendung eine GUI-Anwendung sein soll, die ausgeführten Prozesse jedoch im Hintergrund ausgeführt werden sollten, ohne dass ein interaktives Konsolenfenster angehängt ist. Ich denke, diese Lösung sollte auch funktionieren, wenn der übergeordnete Prozess ein Konsolenprozess ist. Möglicherweise müssen Sie jedoch das Flag "CREATE_NO_WINDOW" entfernen.
Ich habe es geschafft, dies mit GenerateConsoleCtrlEvent () mit einer Wrapper-App zu lösen . Der schwierige Teil ist nur, dass die Dokumentation nicht wirklich klar ist, wie sie genau verwendet werden kann und welche Gefahren damit verbunden sind.
Meine Lösung ist auf das, was beschrieben wird hier . Aber das hat auch nicht wirklich alle Details und mit einem Fehler erklärt. Hier sind die Details, wie man es zum Laufen bringt.
Erstellen Sie eine neue Hilfsanwendung "Helper.exe". Diese Anwendung befindet sich zwischen Ihrer Anwendung (übergeordnet) und dem untergeordneten Prozess, den Sie schließen möchten. Außerdem wird der eigentliche untergeordnete Prozess erstellt. Sie müssen diesen "Middle Man" -Prozess haben, sonst schlägt GenerateConsoleCtrlEvent () fehl.
Verwenden Sie einen IPC-Mechanismus, um vom übergeordneten zum Hilfsprozess zu kommunizieren, dass der Helfer den untergeordneten Prozess schließen soll. Wenn der Helfer dieses Ereignis erhält, ruft er "GenerateConsoleCtrlEvent (CTRL_BREAK, 0)" auf, wodurch er selbst und der untergeordnete Prozess geschlossen werden. Ich habe selbst ein Ereignisobjekt verwendet, das der Elternteil abschließt, wenn er den untergeordneten Prozess abbrechen möchte.
Um Ihre Helper.exe zu erstellen, erstellen Sie sie mit CREATE_NO_WINDOW und CREATE_NEW_PROCESS_GROUP. Wenn Sie den untergeordneten Prozess erstellen, erstellen Sie ihn ohne Flags (0), was bedeutet, dass die Konsole von ihrem übergeordneten Prozess abgeleitet wird. Andernfalls wird das Ereignis ignoriert.
Es ist sehr wichtig, dass jeder Schritt so ausgeführt wird. Ich habe alle Arten von Kombinationen ausprobiert, aber diese Kombination ist die einzige, die funktioniert. Sie können kein CTRL_C-Ereignis senden. Es wird Erfolg zurückgeben, aber vom Prozess ignoriert. CTRL_BREAK ist die einzige, die funktioniert. Das spielt keine Rolle, da beide am Ende ExitProcess () aufrufen.
Sie können GenerateConsoleCtrlEvent () auch nicht mit einer Prozessgruppen-ID der untergeordneten Prozess-ID aufrufen, damit der Hilfsprozess weiterleben kann. Dies wird ebenfalls fehlschlagen.
Ich habe einen ganzen Tag damit verbracht, dies zum Laufen zu bringen. Diese Lösung funktioniert für mich, aber wenn jemand noch etwas hinzuzufügen hat, tun Sie dies bitte. Ich ging durch das Internet und fand viele Leute mit ähnlichen Problemen, aber ohne endgültige Lösung des Problems. Die Funktionsweise von GenerateConsoleCtrlEvent () ist ebenfalls etwas seltsam. Wenn jemand weitere Details dazu kennt, teilen Sie diese bitte mit.
jstack
stattdessen zuverlässig für diese spezielle Angelegenheit verwendet werden kann: stackoverflow.com/a/47723393/603516