Ответ 1
Я думаю, я немного опаздываю на этот вопрос, но я напишу что-нибудь в любом случае для тех, у кого такая же проблема.
Моя проблема похожа на то, что я хочу, чтобы мое приложение было графическим приложением, но выполняемые процессы должны выполняться в фоновом режиме без привязки к окну интерактивной консоли.
Мне удалось решить это с помощью 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() с идентификатором process groupd идентификатора дочернего процесса, который напрямую позволяет вспомогательному процессу продолжать жить. Это также не удастся.
Я потратил целый день, пытаясь заставить это работать. Это решение работает для меня, но если у кого-то есть что-то еще, добавьте, пожалуйста. Я пошел в другую сеть, найдя много людей с подобными проблемами, но не решительное решение проблемы. Как работает GenerateConsoleCtrlEvent(), это также немного странно, поэтому, если кто-то знает более подробные сведения об этом, делитесь им.