Java 在 Windows 中发送任意信号?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/140111/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:47:57  来源:igfitidea点击:

Sending an arbitrary Signal in Windows?

javawindowsutilities

提问by morsch

Linux supports sending an arbitrary Posix-Signal such as SIGINTor SIGTERMto a process using the kill-Command. While SIGINTand SIGTERMare just boring old ways to end a process in a friendly or not-so-friendly kind of way, SIGQUITis 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>.)

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

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

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

However, I have yet to find a way to send a signal to a Windows process.Signals are created by certain user inputs: Ctrl-Ctriggers a SIGINTon 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 killexecutable, 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.

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

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

采纳答案by Joe Pineda

If what you want is to explicitly/programmaticly 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.

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

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).

如果你想要别的东西,请继续阅读(尽管我可能在下面的一些细节上是错的 - 自从我上次仅使用 WinAPI 和 Charles Petzold 的优秀书籍“Programming for Windows”用 C 语言开发 Windows 程序以来已经很久了)。

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.

在 Windows 上,您没有正确的“信号”,WinMain 和 WinProc 从操作系统接收的函数是简单的消息。例如,当您单击窗口的“X”按钮时,Windows 会向该窗口的处理程序发送消息 WM_CLOSE。当窗口被删除但程序仍在运行时,它会发送 WM_DESTROY。当它即将退出主消息处理循环时,WinMain(不是 WinProc)接收 WM_QUIT。您的程序应该按预期响应所有这些 - 您实际上可以通过在收到 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

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

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

回答by Steve K

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.

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

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 JConsoledocumentation.

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

回答by Gustavo Carreno

I'm just wondering if the PsToolsfrom, now Microsoft owned, SysInternalswould help you.

我只是想知道,如果PsTools从,现在微软拥有的Sysinternals会帮助你。

回答by Mike Dimmick

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.

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

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.

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

回答by Bob Nadler

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 FindWindowto send an arbitrary message to another Windows program. e.g.:

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

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

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

回答by rogerdpack

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

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

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

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

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

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