在 Windows 中发送任意信号?

发布于 2024-07-05 11:36:08 字数 924 浏览 11 评论 0原文

Linux 支持使用 kill 命令向进程发送任意 Posix 信号,例如 SIGINTSIGTERM。 虽然 SIGINTSIGTERM 只是以友好或不那么友好的方式结束进程的无聊旧方法,但 SIGQUIT 意味着触发核心转储。 这可以用来触发正在运行的 Java VM 打印出线程转储,包括所有正在运行的线程的堆栈跟踪 - 整洁! 打印调试信息后,Java VM 将继续执行之前所做的操作; 事实上,线程转储仅发生在另一个具有最高优先级的生成线程中。 (您可以使用 kill -3 自行尝试。)

请注意,您还可以使用(不支持!)Signalsun.misc 包中的 SignalHandler 类,因此您可以享受它的各种乐趣。

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

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

Linux supports sending an arbitrary Posix-Signal such as SIGINT or SIGTERM to a process using the kill-Command. While SIGINT and SIGTERM are just boring old ways to end a process in a friendly or not-so-friendly kind of way, SIGQUIT is meant to trigger a core dump. This can be used to trigger a running Java VM to print out a thread dump, including the stacktraces of all running threads -- neat! After printing the debugging info, the Java VM will continue doing whatever it was doing before; in fact the thread dump just happens in another spawned thread of maximum priority. (You can try this out yourself by using kill -3 <VM-PID>.)

Note that you can also register your own signal handlers using the (unsupported!) Signal and SignalHandler classes in the sun.misc-package, so you can have all kinds of fun with it.

However, I have yet to find a way to send a signal to a Windows process. Signals are created by certain user inputs: Ctrl-C triggers a SIGINT on both platforms, for instance. But there does not seem to be any utility to manually send a signal to a running, but non-interactive process on Windows. The obvious solution is to use the Cygwin kill executable, but while it can end Windows processes using the appropriate Windows API, I could not send a SIGBREAK (the Windows equivalent to SIGQUIT) with it; in fact I think the only signal it is able to send to Windows processes is SIGTERM.

So, to make a long story short and to repeat the headline: How to I send an arbitrary signal to a process in Windows?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

祁梦 2024-07-12 11:36:08

SIGINT 和其他信号可以使用 windows-kill 发送到程序(以前是 原作者的 GitHub 上,但现在消失了,还要感谢@NathanOsman,我们有 网络存档< /a> 来源或 网络存档二进制版本的)。

通过语法windows-kill -SIGINT PID使用,其中PID可以通过微软的pslist

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

SIGINT and other signals can be send to program using windows-kill (previously was here on original author's GitHub, but now disappeared, also thanks to @NathanOsman we have web archive of sources or web archive of binary releases).

Using by syntax windows-kill -SIGINT PID, where PID can be obtained by Microsoft's pslist.

Regarding catching SIGINTs, if your program is in Python then you can implement SIGINT processing/catching like in this solution.

余生共白头 2024-07-12 11:36:08

在 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 interop 来完成。

In Windows everything revolves around Win32 messages. I do not believe there is a command line tool to do this, but in C++ you could use FindWindow to send an arbitrary message to another Windows program. e.g.:

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

This can also be done in C# using com interop.

潜移默化 2024-07-12 11:36:08

如果您想要显式/以编程方式终止任何类型的另一个程序/进程,在 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 向该窗口发送消息。

If what you want is to explicitly/programmatically kill another program/process of any kind, within the SysInternals' pstools there is a small tool named "pskill" that behaves just like Unixen "kill" would do.

If you want something else, keep reading (though I may be wrong on some of the specifics below - it's been eons since I last developed a Windows program in C using only the WinAPI and Charles Petzold's excellent books "Programming for Windows" as a guide).

On Windows you don't properly have "signals", what functions WinMain and WinProc receive from the Operating System are simple messages. For instance, when you click on the "X" button of a window, Windows sends that windows' handler the message WM_CLOSE. When the window's deleted but program's still running, it sends WM_DESTROY. When it's about to get out of the main message processing loop, WinMain (not WinProc) receives WM_QUIT. Your program should respond to all these as expected - you can actually develop an "unclosable" application by not doing what it should upon receiving a WM_CLOSE.

When user selects the task from Windows Task Manager and clicks "End Task", the OS will send WM_CLOSE (and another one I don't remember). If you use "End Process", though, the process is killed directly, no messages sent ever (source: The Old New Thing)

I remember there was a way to get the HWND of another process' window, once you get that another process could send that window a message thru functions PostMessage and DispatchMessage.

楠木可依 2024-07-12 11:36:08

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

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

Windows is not POSIX. It does not have signals. The only 'signals' that console programs get is if they call SetConsoleCtrlHandler, in which case it can be notified that the user has pressed Ctrl+C, Ctrl+Break, closed the console window, logged off, or shut the system down.

Everything else is done with IPC, typically with window messages or RPC. Check Sun's documentation to see if there's a way to do what you're asking on the Windows JRE.

蓝咒 2024-07-12 11:36:08

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

它没有回答您原来的问题,但希望能让您得到相同的结果。

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

You can also use jconsole to view the stacktrace of all the running threads. This will work on Windows, and any other OS that supports Java. jconsole also has many other nice features, memory graphs, cpu graphs, etc.

It doesn't answer your original question, but hopefully allows you to get the same results.

If your not familiar with jconsole, check out the Using JConsole documentation.

辞取 2024-07-12 11:36:08

我只是想知道 PsTools 是否来自现在 Microsoft 拥有的, SysInternals 会帮助你。

I'm just wondering if the PsTools from, now Microsoft owned, SysInternals would help you.

带上头具痛哭 2024-07-12 11:36:08

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

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

还有一个与 Windows 等效的“捕获 ctrl+c”方法,我想这就是它的名称。

Ruby is somehow able to (at least emulate) SIGINT SIGKILL etc. on windows, and trap those messages. Might want to check it out.

How ruby does "send signal SIGINT to that process" underneath, in windows, is actually to call TerminateProcess or equivalent on that PID.

There's also a windows equivalent method for "catching ctrl+c" I imagine it's what it calls there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文