在Windows中发送任意信号?

时间:2020-03-06 14:47:24  来源:igfitidea点击:

Linux支持使用kill命令将任意Posix信号(例如SIGINT或者SIGTERM)发送到进程。尽管SIGINT和SIGTERM只是以友好或者不太友好的方式结束进程的无聊旧方法,但SIGQUIT却意在触发核心转储。这可用于触发正在运行的Java VM以打印出线程转储,包括所有正在运行的线程的堆栈跟踪-整洁!在打印调试信息之后,Java VM将继续执行以前的操作;实际上,线程转储仅发生在另一个具有最高优先级的派生线程中。 (我们可以使用kill -3 <VM-PID>自己尝试。)

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

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

因此,总而言之,重复一下标题:如何向Windows中的进程发送任意信号?

解决方案

我们还可以使用jconsole查看所有正在运行的线程的堆栈跟踪。这将在Windows以及任何其他支持Java的操作系统上运行。 jconsole还具有许多其他不错的功能,例如内存图,cpu图等。

它不能回答我们最初的问题,但希望可以使我们获得相同的结果。

如果我们不熟悉jconsole,请查阅《使用JConsole》文档。

我只是想知道现在由Sysinternals拥有的PsTools是否对我们有帮助。

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

这也可以在Cing com interop中完成。

如果我们要明确/以编程方式杀死任何其他程序/进程,则在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向该窗口发送消息。