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

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

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

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

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

Я сам искал сгенерировать дамп стека ... очень жаль, что Sun не добавила такую ​​возможность сделать это из иконки Java в трее.

Jeach 09.12.2010 19:46

Sun предостерегает от использования классов в иерархии com.sun просто потому, что они могут (и делают) произвольно изменяться между версиями, а иногда даже между платформами.

Powerlord 26.09.2008 19:36

Я это знаю, поэтому написал "неподдерживаемый" (восклицательный знак). Это было просто отступление и не главное в вопросе.

morsch 26.09.2008 19:40
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
33
3
37 572
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

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

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

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

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

У меня не сработало (pskillне ведет себя как Ctrl + C или Ctrl + Break ...)

dedek 20.10.2016 16:47

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-взаимодействия.

Ответ принят как подходящий

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

Если вам нужно что-то еще, продолжайте читать (хотя я могу ошибаться в некоторых деталях, приведенных ниже - с тех пор как я последний раз разрабатывал программу 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 отправляет WM_QUIT, по крайней мере, при закрытии окна.

Vladimir Panteleev 11.10.2010 16:50

Ах, вы попросили меня исследовать это ... что всегда хорошо, так как прошло много времени с тех пор, как я разрабатывал напрямую с помощью Win API. Теперь мне стало понятнее.

Joe Pineda 13.10.2010 20:24

это просто поведение приложений пользовательского интерфейса - если ваше приложение не имеет пользовательского интерфейса (например, консольные приложения), этот ответ неверен, одна из возможностей иметь собственное завершение работы или закрытие крючка без пользовательского интерфейса - это msdn.microsoft.com/de-de/library/windows/desktop/…

specializt 18.11.2015 14:07

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

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

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

Пример как?

Jaime Hablutzel 06.04.2017 20:58

ОК добавил еще, или вы хотите пример рубина? :)

rogerdpack 06.04.2017 22:29

SIGINT и другие сигналы могут быть отправлены программе с использованием windows-kill, с помощью синтаксиса windows-kill -SIGINT PID, где PID может быть получен с помощью Microsoft pslist.

Что касается перехвата SIGINT, если ваша программа написана на Python, вы можете реализовать обработку / перехват SIGINT, как в это решение.

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