Отправка произвольного сигнала в 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?


person morsch    schedule 26.09.2008    source источник
comment
Sun предостерегает от использования классов в иерархии com.sun просто потому, что они могут (и делают) произвольно изменяться между версиями, а иногда даже между платформами.   -  person Powerlord    schedule 26.09.2008
comment
Я это знаю, поэтому написал «Неподдерживаемое» (восклицательный знак). Это было просто отступление и не главное в вопросе.   -  person morsch    schedule 26.09.2008
comment
Я сам искал сгенерировать дамп стека ... очень жаль, что Sun не добавила такую ​​возможность, чтобы сделать это с помощью значка Java в трее.   -  person Jeach    schedule 09.12.2010


Ответы (7)


Если вы хотите явно / программно убить другую программу / процесс любого типа, в 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.

person Joe Pineda    schedule 26.09.2008
comment
Я также не думаю, что Windows отправляет WM_QUIT, по крайней мере, при закрытии окна. - person Vladimir Panteleev; 11.10.2010
comment
Ах, вы попросили меня исследовать это ... что всегда хорошо, так как прошло много времени с тех пор, как я разрабатывал напрямую с помощью Win API. Теперь мне стало понятнее. - person Joe Pineda; 13.10.2010
comment
это просто поведение приложений пользовательского интерфейса - если ваше приложение не имеет пользовательского интерфейса (например, консольные приложения), этот ответ неверен, одна из возможностей иметь собственное завершение работы или закрытие ловушки без пользовательского интерфейса - это msdn.microsoft.com/de-de/library/windows/desktop/ - person specializt; 18.11.2015

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

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

person Mike Dimmick    schedule 26.09.2008

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

person Bob Nadler    schedule 26.09.2008

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

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

person Arty    schedule 02.10.2020

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

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

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

person Steve K    schedule 26.09.2008

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

person Gustavo Carreno    schedule 26.09.2008
comment
У меня не сработало (pskill не ведет себя как Ctrl + C или Ctrl + Break ...) - person dedek; 20.10.2016

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

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

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

person rogerdpack    schedule 15.03.2012
comment
Пример как? - person Jaime Hablutzel; 06.04.2017
comment
ОК добавил еще, или вы хотите пример рубина? :) - person rogerdpack; 06.04.2017