Sending an arbitrary Signal in Windows?
Asked Answered
P

7

39

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?

Permenter answered 26/9, 2008 at 15:9 Comment(3)
Sun warns against using classes in the com.sun hierarchy simply because they can (and do) arbitrarily change between versions and sometimes even between platforms.Henkel
I know that, that's why I wrote unsupported (exclamation mark). It was just meant as an aside and isn't central to the question.Permenter
I was looking to generate a stack dump myself... it's too bad Sun didn't add that possibility to do this from the Java tray icon.Railroader
R
19

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.

Remittent answered 26/9, 2008 at 15:58 Comment(3)
I don't think Windows sends a WM_QUIT either, at least not when closing a window.Basel
Ah, you had me research this... which is always a good thing, as its been eons since I developped using the Win API directly. Now I have it clearer.Remittent
thats just the behaviour of UI applications - if your app has no UI (console applications, for instance) this answer is not true, one possibility to have a native shutdown or close-hook without UI is msdn.microsoft.com/de-de/library/windows/desktop/…Mortgagee
M
9

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.

Magnificat answered 26/9, 2008 at 15:20 Comment(0)
F
4

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.

Floe answered 26/9, 2008 at 15:29 Comment(0)
H
3

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.

Historical answered 2/10, 2020 at 5:45 Comment(2)
The windows-kill repository appears to have been hijacked; however, I was able to find a copy of the source code from the latest release through the Web Archive: web.archive.org/web/20200910171157if_/https://…Schematism
@NathanOsman Found another repository that seems to be exact copy of the original one, added this link to my answer. Also thanks to you added your Web Archive link to my answer too. Also there exists web archive of binary releases.Historical
W
1

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.

Warm answered 26/9, 2008 at 15:14 Comment(0)
Y
0

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

Yasukoyataghan answered 26/9, 2008 at 15:15 Comment(1)
Didn't work for me (pskill doesn't behaves as Ctrl+C or Ctrl+Break...)Xenolith
M
0

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.

Marbleize answered 15/3, 2012 at 16:29 Comment(4)
An example of how?Delirious
OK added more, or did you want a ruby example? :)Marbleize
Do you know where in Ruby source it does this?Tupper
See github.com/ruby/ruby/blob/… and thereabouts, also #813586 good luck!Marbleize

© 2022 - 2024 — McMap. All rights reserved.