Выполнить произвольные подпроцессы в Windows и все еще завершиться чисто?

У меня есть приложение A, что я хотел бы иметь возможность вызвать произвольные другие процессы, как определено пользователем в конфигурационном файле.

Сценарий пакетной обработки B является одним таким процессом, пользователь хотел бы быть вызванным A. B настраивает некоторые переменные среды, показывает некоторые сообщения и вызывает компилятор C, чтобы сделать некоторую работу.

Windows обеспечивает стандартный путь к произвольным процессам, которые будут завершены чисто? Предположим, что A выполняется в консоли и получает CTRL+C. Это может передать это на B и C? Предположим, выполнения в окне и пользователе пытаются закрыть окно, оно может отменить B и C?

TerminateProcess является опцией, но не очень хорошей. Если использование TerminateProcess на B, C продолжает работать. Это могло вызвать противные проблемы, если C продолжителен, так как мы могли бы запустить другой экземпляр C для работы на те же файлы, в то время как первая инстанция C все еще тайно на работе. Кроме того, TerminateProcess не приводит к чистому выходу.

GenerateConsoleCtrlEvent звучит хорошим, и мог бы работать, когда все работает в консоли, но в документации говорится, что Вы можете только отправить CTRL+C в свою собственную консоль и так не помогли бы, если A работали в окне.

Действительно ли там кто-либо эквивалентен SIGINT в Windows? Я хотел бы найти статью как этот: http://www.cons.org/cracauer/sigint.html для Windows.

14
задан Weeble 21 September 2009 в 09:01
поделиться

1 ответ

Думаю, я немного опоздал с этим вопросом, но я все равно напишу что-нибудь для тех, у кого есть такая же проблема.

Моя проблема схожа в том, что я хотел бы, чтобы мое приложение было приложением с графическим интерфейсом, но выполняемые процессы должны выполняться в фоновом режиме без прикрепленного окна интерактивной консоли.

Мне удалось решить эту проблему с помощью GenerateConsoleCtrlEvent (). Сложность заключается в том, что в документации не совсем ясно, как именно ее можно использовать и какие подводные камни с ней связаны.

Мое решение основано на том, что описано здесь . Но это тоже не объясняет всех деталей, поэтому вот подробности о том, как заставить его работать.

  1. Создайте новое вспомогательное приложение «Helper.exe». Это приложение будет находиться между вашим приложением (родительским) и дочерним процессом, который вы хотите закрыть. Это также создаст фактический дочерний процесс. У вас должен быть этот процесс «среднего человека», иначе функция GenerateConsoleCtrlEvent () завершится ошибкой.

  2. Используйте какой-то механизм IPC, чтобы сообщить родительскому процессу вспомогательному процессу, что вспомогательный процесс должен закрыть дочерний процесс. Когда помощник получает это событие, он вызывает «GenerateConsoleCtrlEvent (CTRL_BREAK, 0)», который закрывает себя и дочерний процесс. Я сам использовал для этого объект события, который родитель завершает, когда хочет отменить дочерний процесс.

Чтобы создать Helper.exe, создайте его с помощью CREATE_NO_WINDOW и CREATE_NEW_PROCESS_GROUP. И при создании дочернего процесса создайте его без флагов (0), что означает, что он будет унаследовать консоль от своего родителя. В противном случае он проигнорирует событие.

Очень важно, чтобы каждый шаг выполнялся таким образом. Я пробовал всевозможные комбинации, но эта комбинация - единственная, которая работает. Вы не можете отправить событие CTRL_C. Он вернет успех, но будет проигнорирован процессом. CTRL_BREAK - единственный, который работает. На самом деле это не имеет значения, поскольку в конце они оба вызовут ExitProcess ().

Вы также не можете вызвать GenerateConsoleCtrlEvent () с идентификатором группы процессов для идентификатора дочернего процесса, напрямую позволяя вспомогательному процессу продолжать работу. Это тоже не удастся.

Я потратил целый день, пытаясь заставить это работать. Это решение работает для меня, но если у кого-то есть что добавить, сделайте это. Я обошел всю сеть и нашел много людей с похожими проблемами, но не нашел определенного решения проблемы. Как работает GenerateConsoleCtrlEvent (), тоже немного странно, поэтому, если кто-нибудь знает о нем более подробную информацию, поделитесь.

9
ответ дан 1 December 2019 в 13:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: