Supongo que llego un poco tarde en esta pregunta, pero de todos modos escribiré algo para cualquiera que tenga el mismo problema. Esta es la misma respuesta que le di a esta pregunta.
Mi problema era que me gustaría que mi aplicación fuera una aplicación GUI, pero los procesos ejecutados deberían ejecutarse en segundo plano sin ninguna ventana de consola interactiva adjunta. Creo que esta solución también debería funcionar cuando el proceso principal es un proceso de consola. Sin embargo, es posible que deba eliminar la bandera "CREATE_NO_WINDOW".
Logré resolver esto usando GenerateConsoleCtrlEvent () con una aplicación contenedora. La parte complicada es que la documentación no es realmente clara sobre cómo se puede usar y los inconvenientes que conlleva.
Mi solución se basa en lo que se describe aquí . Pero eso tampoco explicó todos los detalles y con un error, así que aquí están los detalles sobre cómo hacerlo funcionar.
Cree una nueva aplicación de ayuda "Helper.exe". Esta aplicación se ubicará entre su aplicación (padre) y el proceso hijo que desea poder cerrar. También creará el proceso hijo real. Debe tener este proceso de "intermediario" o GenerateConsoleCtrlEvent () fallará.
Utilice algún tipo de mecanismo de IPC para comunicar del padre al proceso auxiliar que el ayudante debe cerrar el proceso hijo. Cuando el asistente obtiene este evento, llama a "GenerateConsoleCtrlEvent (CTRL_BREAK, 0)", que se cierra a sí mismo y al proceso hijo. Usé un objeto de evento para esto yo mismo que el padre completa cuando quiere cancelar el proceso secundario.
Para crear su Helper.exe, créelo con CREATE_NO_WINDOW y CREATE_NEW_PROCESS_GROUP. Y al crear el proceso hijo, créelo sin marcas (0), lo que significa que derivará la consola de su padre. Si no lo hace, se ignorará el evento.
Es muy importante que cada paso se haga así. He estado probando diferentes tipos de combinaciones, pero esta combinación es la única que funciona. No puede enviar un evento CTRL_C. Devolverá el éxito, pero el proceso lo ignorará. CTRL_BREAK es el único que funciona. Realmente no importa ya que ambos llamarán a ExitProcess () al final.
Tampoco puede llamar a GenerateConsoleCtrlEvent () con una identificación de grupo de proceso de la identificación del proceso secundario, lo que permite que el proceso auxiliar continúe viviendo. Esto también fallará.
Pasé un día entero tratando de que esto funcionara. Esta solución funciona para mí, pero si alguien tiene algo más que agregar, hágalo. Busqué por toda la red muchas personas con problemas similares pero sin una solución definitiva al problema. El funcionamiento de GenerateConsoleCtrlEvent () también es un poco extraño, así que si alguien conoce más detalles al respecto, compártelo.
jstack
puede usar de manera confiable en su lugar para este asunto específico: stackoverflow.com/a/47723393/603516