Отправка произвольного сигнала в Windows?

Linux поддерживает отправку произвольного Posix-сигнала, такого как SIGINT или SIGTERM в процессе использования kill-команды. В то время как SIGINT и SIGTERM просто скучные старые способы закончить процесс в дружественном или не очень дружественном виде,SIGQUIT предназначен для запуска дампа ядра. Это можно использовать для запуска Java VM для печати дампа потока, включая stacktraces всех запущенных потоков-аккуратно! После печати отладочной информации Java VM продолжит делать все, что угодно это было раньше; на самом деле дамп потока просто происходит в другом порожденном потоке с максимальным приоритетом. (Вы можете попробовать это самостоятельно, используя kill -3 <VM-PID>.)

обратите внимание, что вы также можете зарегистрировать свои собственные обработчики сигналов, используя (неподдерживаемый!) Signal и SignalHandler классы sun.misc-пакет, так что вы можете повеселиться с ним.

однако мне еще предстоит найти способ отправить сигнал процессу Windows. сигналы создаются определенные входные данные пользователя:Ctrl-C вызывает SIGINT на обеих платформах, например. Но там, кажется, не быть любой утилиты вручную отправить сигнал на запуск, но не интерактивный процесс в Windows. Очевидным решением является использование Cygwin kill исполняемый файл, но, хотя он может завершить процессы Windows с помощью соответствующего Windows API, я не мог отправить SIGBREAK (Windows эквивалентно SIGQUIT) С ним; на самом деле я думаю, что единственный сигнал, который он может отправить процессам Windows, это SIGTERM.

Итак, чтобы сделать длинную историю короткой и повторить заголовок: Как отправить произвольный сигнал процессу в Windows?

6 ответов


Если вы хотите явно / программно убить другую программу / процесс любого рода, в pstools SysInternals есть небольшой инструмент с именем "pskill", который ведет себя так же, как Unixen "kill".

Если вы хотите что-то еще, продолжайте читать (хотя я могу ошибаться в некоторых деталях ниже - прошли эпохи с тех пор, как я в последний раз разрабатывал программу Windows на C, используя только отличные книги WinAPI и Чарльза Петцольда "программирование для Windows" в качестве руководство.)

в Windows у вас нет "сигналов", какие функции WinMain и WinProc получают от операционной системы, просты сообщения. Например, когда вы нажимаете на кнопку" X " окна, Windows отправляет обработчику windows сообщение WM_CLOSE. Когда окно удалено, но программа все еще работает, оно отправляет WM_DESTROY. Когда он собирается выйти из основного цикла обработки сообщений, WinMain (не WinProc) получает WM_QUIT. Ваша программа должна ответьте на все это, как ожидалось - вы можете разработать "unclosable" приложение, не делая то, что он должен при получении WM_CLOSE.

когда пользователь выбирает задачу из Диспетчера задач Windows и нажимает "End Task", ОС отправляет WM_CLOSE (и еще один, который я не помню). Если вы используете "End Process", процесс убивается напрямую, никаких сообщений не отправляется никогда (источник:Старая Новая Вещь

Я помню, что был способ получить HWND окно другого процесса, как только вы получите, что другой процесс может отправить это окно сообщение через функции PostMessage и DispatchMessage.


Windows не является POSIX. У него нет сигналов. Единственные "сигналы", которые получают консольные программы, - это если они вызывают SetConsoleCtrlHandler, в этом случае можно уведомить, что пользователь нажал Ctrl+C, Ctrl+Break, закрыл окно консоли, вышел из системы или выключил систему.

все остальное делается с помощью IPC, обычно с оконными сообщениями или RPC. Проверьте документацию Sun, чтобы узнать, есть ли способ сделать то, что вы просите в Windows JRE.


в Windows все вращается вокруг сообщений Win32. Я не верю, что для этого есть инструмент командной строки, но в C++ вы можете использовать FindWindow для отправки произвольного сообщения в другую программу Windows. например:

#define WM_MYMSG  ( WM_USER+0x100 )
HWND h = ::FindWindow(NULL,_T("Win32App"));
if (h) {
    ::PostMessage(h, WM_MYMSG, 0, 0);
}

Это также можно сделать в C# с помощью com-взаимодействия.


вы также можете использовать jconsole для просмотра stacktrace всех запущенных потоков. Это будет работать на Windows, и любой другой ОС, которая поддерживает Java. утилиты jconsole также имеет много других хороших функций, графики, памяти, процессора, графики и т. д.

Он не отвечает на ваш первоначальный вопрос, но, надеюсь, позволит вам получить те же результаты.

Если вы не знакомы с jconsole, проверьте Использование JConsole документация.


Мне просто интересно, если PsTools от, теперь Microsoft принадлежит,SysInternals поможет вам.


Ruby каким-то образом может (по крайней мере, эмулировать) SIGINT SIGKILL и т. д. в windows и ловушка этих сообщений. Возможно, захотите, чтобы проверить его.

как ruby делает "send signal SIGINT to that process" внизу, в windows, на самом деле вызывает TerminateProcess или эквивалент на этом PID.

есть также эквивалентный метод windows для "ловли ctrl+c" я предполагаю, что это то, что он вызывает там.