Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

Это также можно сделать в С# с помощью com interop.

Ответ 4

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

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

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

Ответ 5

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

Ответ 6

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

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

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