web-dev-qa-db-ja.com

Windowsで任意のシグナルを送信しますか?

Linuxは、SIGINT-コマンドを使用したプロセスへのSIGTERMkillなどの任意のPosix-Signalの送信をサポートしています。 SIGINTSIGTERMは、プロセスを友好的またはあまり友好的ではない方法で終了するための退屈な古い方法ですが、SIGQUITはコアダンプをトリガーすることを目的としています。これを使用して、実行中のJava VMをトリガーし、実行中のすべてのスレッドのスタックトレースを含むスレッドダンプを出力できます-きちんと!デバッグを出力した後info、Java VMは、以前と同じように実行し続けます。実際、スレッドダンプは、最大優先度の別の生成されたスレッドで発生します(できます)。 kill -3 <VM-PID>を使用して、これを自分で試してください。)

Sun.misc-パッケージの(サポートされていない!)SignalクラスとSignalHandlerクラスを使用して、独自のシグナルハンドラーを登録することもできるため、あらゆる種類の楽しみを味わうことができます。

ただし、Windowsプロセスにシグナルを送信する方法はまだ見つかりません。シグナルは特定のユーザー入力によって作成されます。たとえば、Ctrl-Cは両方のプラットフォームでSIGINTをトリガーします。しかし、Windows上で実行中の非対話型プロセスに手動でシグナルを送信するユーティリティはないようです。明らかな解決策は、Cygwin kill実行可能ファイルを使用することですが、適切なWindows APIを使用してWindowsプロセスを終了することはできますが、SIGBREAKSIGQUITに相当するWindows)を一緒に送信できませんでした。実際、Windowsプロセスに送信できるシグナルはSIGTERMだけだと思います。

したがって、長い話を短くして見出しを繰り返すには、Windowsのプロセスに任意のシグナルを送信するにはどうすればよいですか?

28
morsch

明示的/プログラム的に任意の種類の別のプログラム/プロセスを強制終了する場合は、SysInternalsのpstools内に、Unixenの「kill」と同じように動作する「pskill」という名前の小さなツールがあります。

他に何か必要な場合は、読み続けてください(ただし、以下の詳細のいくつかについては間違っている可能性があります。WinAPIとCharlesPetzoldの優れた書籍「ProgrammingforWindows」のみをガイドとして使用して、CでWindowsプログラムを最後に開発してからずっと経ちました。 )。

Windowsでは、適切に「シグナル」がありません。WinMainとWinProcがオペレーティングシステムから受け取る関数は単純ですメッセージ。たとえば、ウィンドウの[X]ボタンをクリックすると、WindowsはそのウィンドウのハンドラーにメッセージWM_CLOSEを送信します。ウィンドウが削除されてもプログラムがまだ実行されている場合、ウィンドウはWM_DESTROYを送信します。メインメッセージ処理ループから抜け出そうとすると、WinMain(WinProcではない)がWM_QUITを受け取ります。プログラムはこれらすべてに期待どおりに応答する必要があります。WM_CLOSEを受け取ったときに実行しないことで、実際には「閉じられない」アプリケーションを開発できます。

ユーザーがWindowsタスクマネージャーからタスクを選択して[タスクの終了]をクリックすると、OSはWM_CLOSE(および私が覚えていない別のタスク)を送信します。ただし、「End Process」を使用すると、プロセスは直接強制終了され、メッセージは送信されません(ソース: The Old New Thing

別のプロセスのウィンドウのHWNDを取得する方法があったことを覚えています。取得すると、別のプロセスがそのウィンドウに関数PostMessageおよびDispatchMessageを介してメッセージを送信できるようになります。

13
Joe Pineda

WindowsはPOSIXではありません。信号はありません。コンソールプログラムが取得する唯一の「シグナル」は、SetConsoleCtrlHandlerを呼び出した場合です。この場合、ユーザーがCtrl + C、Ctrl + Breakを押した、コンソールウィンドウを閉じた、ログオフした、またはシャットダウンしたことを通知できます。システムがダウンしています。

それ以外はすべてIPCで行われ、通常はウィンドウメッセージまたはRPCで行われます。 Sunのドキュメントをチェックして、WindowsJREで求めていることを実行する方法があるかどうかを確認してください。

8
Mike Dimmick

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

これは、com相互運用機能を使用してC#で実行することもできます。

3
Bob Nadler

Jconsoleを使用して、実行中のすべてのスレッドのスタックトレースを表示することもできます。これは、WindowsおよびJavaをサポートするその他のOSで機能します。 jconsoleには、他にも多くの優れた機能、メモリグラフ、CPUグラフなどがあります。

それはあなたの元の質問に答えませんが、うまくいけば同じ結果を得ることができます。

Jconsoleに慣れていない場合は、 JConsoleの使用 ドキュメントを確認してください。

1
Steve K

Rubyはどういうわけか(少なくとも)Windows上のSIGINT SIGKILLなどをエミュレートし、それらのメッセージをトラップすることができます。それをチェックしたいかもしれません。

WindowsでRubyがそのプロセスにシグナルSIGINTを送信する」方法は、実際にはそのPIDでTerminateProcessまたは同等のものを呼び出すことです。

「ctrl + cをキャッチする」ためのWindowsと同等の方法もあります。私はそれがそこで呼ばれているものだと思います。

0
rogerdpack

PsTools from、現在Microsoftが所有している、 SysInternals が役立つかどうか疑問に思っています。

0
Gustavo Carreno