Immagino di essere un po 'in ritardo su questa domanda, ma scriverò comunque qualcosa per chiunque abbia lo stesso problema. Questa è la stessa risposta che ho dato a questa domanda.
Il mio problema era che vorrei che la mia applicazione fosse un'applicazione GUI, ma i processi eseguiti dovrebbero essere eseguiti in background senza alcuna finestra della console interattiva collegata. Penso che questa soluzione dovrebbe funzionare anche quando il processo genitore è un processo della console. Tuttavia, potresti dover rimuovere il flag "CREATE_NO_WINDOW".
Sono riuscito a risolverlo utilizzando GenerateConsoleCtrlEvent () con un'app wrapper. La parte difficile è solo che la documentazione non è molto chiara su come può essere utilizzata e sulle insidie.
La mia soluzione si basa su quanto descritto qui . Ma anche questo non ha spiegato tutti i dettagli e con un errore, quindi ecco i dettagli su come farlo funzionare.
Crea una nuova applicazione di supporto "Helper.exe". Questa applicazione si troverà tra la tua applicazione (genitore) e il processo figlio che vuoi poter chiudere. Creerà anche il processo figlio effettivo. È necessario disporre di questo processo "intermediario" altrimenti GenerateConsoleCtrlEvent () fallirà.
Usa un qualche tipo di meccanismo IPC per comunicare dal processo genitore al processo di supporto che l'helper dovrebbe chiudere il processo figlio. Quando l'helper ottiene questo evento, chiama "GenerateConsoleCtrlEvent (CTRL_BREAK, 0)" che chiude se stesso e il processo figlio. Ho usato un oggetto evento per questo io stesso che il genitore completa quando vuole annullare il processo figlio.
Per creare il tuo Helper.exe, crealo con CREATE_NO_WINDOW e CREATE_NEW_PROCESS_GROUP. E quando si crea il processo figlio, crearlo senza flag (0), il che significa che deriverà la console dal suo genitore. In caso contrario, ignorerà l'evento.
È molto importante che ogni passaggio venga eseguito in questo modo. Ho provato tutti i diversi tipi di combinazioni, ma questa è l'unica che funziona. Non puoi inviare un evento CTRL_C. Restituirà il successo ma verrà ignorato dal processo. CTRL_BREAK è l'unico che funziona. Non ha molta importanza dal momento che entrambi chiameranno ExitProcess () alla fine.
Inoltre, non puoi chiamare GenerateConsoleCtrlEvent () con un process groupd id dell'id del processo figlio, consentendo direttamente al processo di supporto di continuare a vivere. Anche questo fallirà.
Ho passato un'intera giornata a cercare di farlo funzionare. Questa soluzione funziona per me, ma se qualcuno ha qualcos'altro da aggiungere, fallo. Sono andato in tutta la rete trovando molte persone con problemi simili ma nessuna soluzione definitiva al problema. Anche il modo in cui funziona GenerateConsoleCtrlEvent () è un po 'strano, quindi se qualcuno conosce maggiori dettagli su di esso, condividilo.
jstack
possa essere utilizzato in modo affidabile invece per questo argomento specifico: stackoverflow.com/a/47723393/603516