Acho que estou um pouco atrasado nessa questão, mas vou escrever algo de qualquer maneira para qualquer pessoa com o mesmo problema. Esta é a mesma resposta que dei a esta pergunta.
Meu problema era que eu gostaria que meu aplicativo fosse um aplicativo GUI, mas os processos executados deveriam ser executados em segundo plano, sem nenhuma janela de console interativo anexada. Acho que essa solução também deve funcionar quando o processo pai é um processo de console. Você pode ter que remover o sinalizador "CREATE_NO_WINDOW".
Consegui resolver isso usando GenerateConsoleCtrlEvent () com um aplicativo wrapper. A parte complicada é apenas que a documentação não é realmente clara sobre como exatamente pode ser usado e as armadilhas com ele.
Minha solução é baseada no que está descrito aqui . Mas isso também não explicava realmente todos os detalhes e com um erro, então aqui estão os detalhes de como fazer isso funcionar.
Crie um novo aplicativo auxiliar "Helper.exe". Este aplicativo ficará entre o seu aplicativo (pai) e o processo filho que você deseja fechar. Ele também criará o processo filho real. Você deve ter este processo de "intermediário" ou GenerateConsoleCtrlEvent () falhará.
Use algum tipo de mecanismo IPC para comunicar do pai para o processo auxiliar que o auxiliar deve fechar o processo filho. Quando o auxiliar obtém este evento, ele chama "GenerateConsoleCtrlEvent (CTRL_BREAK, 0)" que fecha a si mesmo e ao processo filho. Eu mesmo usei um objeto de evento para isso, que o pai conclui quando deseja cancelar o processo filho.
Para criar seu Helper.exe, crie-o com CREATE_NO_WINDOW e CREATE_NEW_PROCESS_GROUP. E ao criar o processo filho, crie-o sem sinalizadores (0), o que significa que ele derivará o console de seu pai. Deixar de fazer isso fará com que ele ignore o evento.
É muito importante que cada etapa seja executada assim. Tenho tentado todos os tipos de combinações, mas essa combinação é a única que funciona. Você não pode enviar um evento CTRL_C. Ele retornará sucesso, mas será ignorado pelo processo. CTRL_BREAK é o único que funciona. Realmente não importa, pois ambos chamarão ExitProcess () no final.
Você também não pode chamar GenerateConsoleCtrlEvent () com um ID de grupo de processo do ID do processo filho, permitindo diretamente que o processo auxiliar continue ativo. Isso também falhará.
Passei um dia inteiro tentando fazer isso funcionar. Esta solução funciona para mim, mas se alguém tiver mais alguma coisa a acrescentar, faça-o. Eu procurei por toda a rede muitas pessoas com problemas semelhantes, mas nenhuma solução definitiva para o problema. Como GenerateConsoleCtrlEvent () funciona também é um pouco estranho, então se alguém souber mais detalhes sobre ele, compartilhe.
jstack
pode ser usado de forma confiável para este assunto específico: stackoverflow.com/a/47723393/603516