题
Linux 支持发送任意 Posix 信号,例如 SIGINT
或者 SIGTERM
到一个使用的过程 kill
-命令。尽管 SIGINT
和 SIGTERM
只是无聊的旧方法以友好或不那么友好的方式结束一个过程, SIGQUIT
旨在触发核心转储。这可以用来触发正在运行的 Java VM 打印出线程转储,包括所有正在运行的线程的堆栈跟踪 - 整洁!打印调试信息后,Java VM 将继续执行之前所做的操作;事实上,线程转储仅发生在另一个具有最高优先级的生成线程中。(您可以通过使用自己尝试一下 kill -3 <VM-PID>
.)
请注意,您还可以使用(不支持!) Signal
和 SignalHandler
课程在 sun.misc
- 包,让您可以享受各种乐趣。
但是,我还没有找到向 Windows 进程发送信号的方法。 信号是由某些用户输入创建的: Ctrl-C
触发一个 SIGINT
例如,在两个平台上。但似乎没有任何实用程序可以手动向 Windows 上正在运行的非交互式进程发送信号。显而易见的解决方案是使用 Cygwin kill
可执行文件,但是虽然它可以使用适当的 Windows API 结束 Windows 进程,但我无法发送 SIGBREAK
(Windows 相当于 SIGQUIT
) 用它;事实上,我认为它能够发送到 Windows 进程的唯一信号是 SIGTERM
.
因此,长话短说并重复标题:如何向 Windows 中的进程发送任意信号?
解决方案
如果您想要显式/以编程方式终止任何类型的另一个程序/进程,在 SysInternals 的 pstools 中,有一个名为“pskill”的小工具,其行为就像 Unixen“kill”一样。
如果您想要其他内容,请继续阅读(尽管我在下面的一些细节上可能是错误的 - 自从我上次仅使用 WinAPI 和 Charles Petzold 的优秀书籍“Windows 编程”作为指南用 C 语言开发 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 interop 来完成。
您还可以使用 jconsole 查看所有正在运行的线程的堆栈跟踪。这适用于 Windows 以及支持 Java 的任何其他操作系统。jconsole 还有许多其他不错的功能,内存图、CPU 图等。
它没有回答您原来的问题,但希望能让您得到相同的结果。
如果您不熟悉 jconsole,请查看 使用 JConsole 文档。
Ruby 以某种方式能够(至少模拟)SIGINT SIGKILL 等。在 Windows 上,并捕获这些消息。可能想检查一下。
ruby 在 windows 下如何“向该进程发送信号 SIGINT”,实际上是调用 TerminateProcess
或该 PID 上的等效项。
还有一个与 Windows 等效的“捕获 ctrl+c”方法,我想这就是它的名称。