2017-02-17 9 views
4

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

В UNIX я могу это сделать, отправив SIGTERM, и если процесс не закончится, я могу жестоко убить его SIGKILL.

В Windows я изо всех сил пытаюсь найти альтернативу сценарию SIGTERM. Я узнал, что есть taskkill /PID XXXX (без /f!), Но

  1. Я не нашел никакой информации о том, что taskkill /PID XXXX делает под капотом, поэтому я не могу проверить это. Я не могу найти, как обрабатывать то, что отправляет taskkill /PID XXXX со стороны процесса.
  2. Он не работает с командами в cmd.exe. Я пытался запустить простой процесс сервера в одном cmd.exe, получить его PID и в другом окне, чтобы taskkill /PID XXXX, но Taskkill отказался сделать это: ERROR: The process with PID XXXX could not be terminated. Reason: This process can only be terminated forcefully (with /F option).

Так что мой вопрос: Как информирует процесс командной строки в Windows, что он должен завершиться без принудительного завершения? Как получать и обрабатывать такое сообщение на стороне, которая должна быть завершена?

ответ

3

GenerateConsoleCtrlEvent сигнализирует консольное приложение, как если бы пользователь нажал Ctrl + C или Ctrl + Break. Консольные приложения могут игнорировать эти сигналы (используя SetContolCtrlHandler), но по умолчанию они просто выполняют ExitProcess.

Это тот же сигнал, который использует Windows, когда пользователь закрывает окно консоли, выходит из системы или выключается.

+0

Вы знаете, как я могу отправить эти сигналы с языка программирования, например JavaScript (node.js)? –

+0

@HonzaJavorek: Извините, я этого не делаю. Может быть, вы должны добавить соответствующий тег языка к вопросу, чтобы люди, которые знают, замечают вопрос. –

3

TaskKill использует PostMessage(hwnd, WM_CLOSE, 0, 0); (в основном то же, что нажатие X на окне), если процесс имеет видимое окно.

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