35

Linux 支持使用 -Command 向进程发送任意 Posix 信号,例如SIGINT或。虽然并且只是以友好或不那么友好的方式结束进程的无聊旧方法,但旨在触发核心转储。这可用于触发正在运行的 Java VM 打印出线程转储,包括所有正在运行的线程的堆栈跟踪——太棒了!打印调试信息后,Java VM 将继续执行之前的操作;事实上,线程转储只是发生在另一个具有最高优先级的衍生线程中。(您可以使用 自己尝试一下。)SIGTERMkillSIGINTSIGTERMSIGQUITkill -3 <VM-PID>

Signal请注意,您还可以使用 -package 中的(不支持!)和SignalHandler类来注册自己的信号处理程序sun.misc,因此您可以从中获得各种乐趣。

但是,我还没有找到向 Windows 进程发送信号的方法。信号由某些用户输入创建:例如,在两个平台上Ctrl-C触发。SIGINT但似乎没有任何实用程序可以手动向 Windows 上正在运行但非交互式进程发送信号。显而易见的解决方案是使用 Cygwinkill可执行文件,但是虽然它可以使用适当的 Windows API 结束 Windows 进程,但我无法使用它发送SIGBREAK(相当于 Windows 的SIGQUIT);事实上,我认为它能够发送到 Windows 进程的唯一信号是SIGTERM.

因此,长话短说并重复标题:如何向 Windows 中的进程发送任意信号?

4

7 回答 7

17

如果您想要显式/以编程方式杀死任何类型的另一个程序/进程,那么在 SysInternals 的 pstools 中有一个名为“pskill”的小工具,其行为就像 Unixen“kill”一样。

如果您想要其他内容,请继续阅读(尽管我可能对以下某些细节有误 - 自从我上次仅使用 WinAPI 和 Charles Petzold 的优秀书籍“Programming for Windows”作为指南用 C 语言开发 Windows 程序以来,已经有好多年了)。

在 Windows 上,您没有适当的“信号”,WinMain 和 WinProc 从操作系统接收的功能是简单的消息。例如,当您单击窗口的“X”按钮时,Windows 会向该窗口的处理程序发送消息 WM_CLOSE。当窗口被删除但程序仍在运行时,它会发送 WM_DESTROY。当它即将退出主消息处理循环时,WinMain(不是 WinProc)收到 WM_QUIT。您的程序应该按预期响应所有这些 - 您实际上可以通过在收到 WM_CLOSE 时不做它应该做的事情来开发一个“不可关闭”的应用程序。

当用户从 Windows 任务管理器中选择任务并单击“结束任务”时,操作系统将发送 WM_CLOSE(另一个我不记得了)。但是,如果您使用“结束进程”,该进程会直接被终止,不会发送任何消息(来源:The Old New Thing

我记得有一种方法可以获取另一个进程窗口的 HWND,一旦你知道另一个进程可以通过函数 PostMessage 和 DispatchMessage 向该窗口发送消息。

于 2008-09-26T15:58:44.030 回答
9

Windows 不是 POSIX。它没有信号。控制台程序获得的唯一“信号”是调用SetConsoleCtrlHandler,在这种情况下,可以通知用户已按下 Ctrl+C、Ctrl+Break、关闭控制台窗口、注销或关闭系统。

其他一切都使用 IPC 完成,通常使用窗口消息或 RPC。查看 Sun 的文档,看看是否有办法在 Windows JRE 上执行您所要求的操作。

于 2008-09-26T15:20:44.277 回答
4

在 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);
}

这也可以使用 com interop 在 C# 中完成。

于 2008-09-26T15:29:24.630 回答
2

SIGINT 和其他信号可以通过windows-kill发送到程序,通过语法windows-kill -SIGINT PIDPID可以通过微软的pslist获得。

关于捕获 SIGINT,如果您的程序使用 Python,那么您可以像在此解决方案中那样实现 SIGINT 处理/捕获。

于 2020-10-02T05:45:18.553 回答
1

您还可以使用 jconsole 查看所有正在运行的线程的堆栈跟踪。这将适用于 Windows 和任何其他支持 Java 的操作系统。jconsole 还有很多其他不错的特性,内存图,cpu 图等。

它没有回答您最初的问题,但希望可以让您获得相同的结果。

如果您不熟悉 jconsole,请查看使用 JConsole文档。

于 2008-09-26T15:14:33.573 回答
0

我只是想知道现在 Microsoft 拥有的SysInternals的PsTools是否会对您有所帮助。

于 2008-09-26T15:15:25.413 回答
0

Ruby 以某种方式能够(至少模拟)Windows 上的 SIGINT SIGKILL 等,并捕获这些消息。可能想检查一下。

在 Windows 中,ruby 如何“向该进程发送信号 SIGINT”实际上是TerminateProcess在该 PID 上调用或等效。

还有一种用于“捕获 ctrl+c”的 Windows 等效方法,我想这就是它在那里所说的。

于 2012-03-15T16:29:21.407 回答