Вопрос

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

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

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

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

Это было полезно?

Решение

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

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

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

Когда пользователь выбирает задачу в диспетчере задач Windows и нажимает «Завершить задачу», ОС отправляет WM_CLOSE (и еще один, я не помню).Однако если вы используете «Завершить процесс», процесс завершается напрямую, никаких сообщений не отправляется (источник: Старая новая вещь

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

Другие советы

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

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

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

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

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

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

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

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

Мне просто интересно, если PsИнструменты от, теперь принадлежащей Microsoft, SysInternals помог бы вам.

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

Как Ruby «отправляет сигнал SIGINT этому процессу» внизу, в Windows, на самом деле означает вызов TerminateProcess или эквивалент этого PID.

Существует также эквивалентный метод Windows для «перехвата Ctrl + C», я думаю, это то, что он там вызывает.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top