Отправка произвольного сигнала в 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" я предполагаю, что это то, что он вызывает там.