Полагаю, я немного опоздал с этим вопросом, но в любом случае напишу что-нибудь для тех, у кого такая же проблема.
Это тот же ответ, который я дал на этот вопрос.
Моя проблема заключалась в том, что я хотел бы, чтобы мое приложение было приложением с графическим интерфейсом, но выполняемые процессы должны выполняться в фоновом режиме без какого-либо окна интерактивной консоли. Я думаю, что это решение также должно работать, когда родительский процесс является консольным процессом. Возможно, вам придется удалить флаг "CREATE_NO_WINDOW".
Мне удалось решить эту проблему с помощью GenerateConsoleCtrlEvent () с приложением-оболочкой. Сложность в том, что в документации не совсем ясно, как именно ее можно использовать и какие подводные камни с ней связаны.
Мое решение основано на том, что описано здесь . Но это на самом деле не объяснило все детали и с ошибкой, так что вот подробности о том, как заставить это работать.
Создайте новое вспомогательное приложение "Helper.exe". Это приложение будет находиться между вашим приложением (родительским) и дочерним процессом, который вы хотите закрыть. Это также создаст фактический дочерний процесс. У вас должен быть этот процесс "среднего человека", иначе GenerateConsoleCtrlEvent () завершится неудачей.
Используйте какой-нибудь механизм IPC для связи от родительского процесса к вспомогательному процессу о том, что помощник должен закрыть дочерний процесс. Когда помощник получает это событие, он вызывает «GenerateConsoleCtrlEvent (CTRL_BREAK, 0)», который закрывает себя и дочерний процесс. Я сам использовал для этого объект события, который родитель завершает, когда хочет отменить дочерний процесс.
Чтобы создать свой Helper.exe, создайте его с помощью CREATE_NO_WINDOW и CREATE_NEW_PROCESS_GROUP. А при создании дочернего процесса создайте его без флагов (0), что означает, что он получит консоль от своего родителя. Невыполнение этого условия приведет к игнорированию события.
Очень важно, чтобы каждый шаг выполнялся следующим образом. Я пробовал разные комбинации, но эта комбинация единственная, которая работает. Вы не можете отправить событие CTRL_C. Это вернет успех, но будет проигнорировано процессом. CTRL_BREAK - единственный, который работает. Не имеет большого значения, так как они оба в конце вызовут ExitProcess ().
Вы также не можете вызвать GenerateConsoleCtrlEvent () с идентификатором группы процессов, непосредственно идентифицирующим дочерний процесс, что позволяет вспомогательному процессу продолжать работу. Это также не удастся.
Я провел целый день, пытаясь заставить это работать. Это решение работает для меня, но если у кого-то есть что-то еще, пожалуйста, сделайте. Я ходил по сети, находя множество людей с похожими проблемами, но без определенного решения проблемы. Принцип работы GenerateConsoleCtrlEvent () также немного странный, поэтому, если кто-то знает о нем больше подробностей, пожалуйста, поделитесь.