Я предполагаю, что я немного опоздал на этот вопрос, но я буду писать что-то в любом случае для тех, кто с той же проблемой. Это тот же ответ, что и я задал вопрос this.
Моя проблема заключалась в том, что я хотел бы, чтобы мое приложение было графическим приложением, но выполняемые процессы должны выполняться в фоновом режиме без подключения интерактивного консольного окна. Я думаю, что это решение также должно работать, когда родительский процесс является консольным процессом. Возможно, вам придется удалить флаг CREATE_NO_WINDOW.
Мне удалось решить это, используя GenerateConsoleCtrlEvent() с помощью приложения-обертки. Трудная часть заключается в том, что документация не совсем понятна, как именно ее можно использовать и с ней ловушки.
Мое решение основано на том, что описано here. Но на самом деле это не объясняло все детали и с ошибкой, поэтому вот подробности о том, как заставить ее работать.
Создайте новое вспомогательное приложение «Helper.exe». Это приложение будет находиться между вашим приложением (родителем) и дочерним процессом, который вы хотите закрыть. Он также создаст фактический детский процесс. У вас должен быть этот процесс «средний человек», иначе GenerateConsoleCtrlEvent() завершится с ошибкой.
Используйте какой-то механизм IPC для связи от родителя к вспомогательному процессу, который помощник должен закрыть дочерний процесс. Когда помощник получает это событие, он вызывает «GenerateConsoleCtrlEvent (CTRL_BREAK, 0)», который закрывает сам себя и дочерний процесс. Я использовал объект события для этого сам, который родитель завершает, когда он хочет отменить дочерний процесс.
Чтобы создать свой файл Helper.exe, создайте его с помощью CREATE_NO_WINDOW и CREATE_NEW_PROCESS_GROUP. И при создании дочернего процесса создайте его без флагов (0), то есть он выведет консоль из своего родителя. В противном случае это приведет к игнорированию события.
Очень важно, чтобы каждый шаг выполнялся следующим образом. Я пробовал всевозможные комбинации, но эта комбинация - единственная, которая работает. Вы не можете отправить событие CTRL_C. Это вернет успех, но процесс будет проигнорирован. CTRL_BREAK - единственный, который работает. Не имеет значения, так как в конце концов они вызовут ExitProcess().
Вы также не можете вызвать GenerateConsoleCtrlEvent() с id группы процессов id дочернего процесса, что позволяет процессу поддержки продолжать жить. Это тоже не удастся.
Я потратил целый день, пытаясь заставить это работать. Это решение работает для меня, но если у кого-то есть что-то еще, добавьте, пожалуйста. Я пошел по сети, найдя много людей с подобными проблемами, но без определенного решения проблемы. Как работает GenerateConsoleCtrlEvent(), это также немного странно, поэтому, если кто-то знает более подробную информацию об этом, пожалуйста, поделитесь.
Я был заинтересован в посылке Ctrl-C для процессов Java услуг только для получения threaddumps. Похоже, что «jstack» может быть надежно использован для этого конкретного вопроса: https://stackoverflow.com/a/47723393/603516 – Vadzim