+シグナルGenerateConsoleCtrlEvent()
の送信に使用することが正しい答えであるという事実にもかかわらず、さまざまな .NET アプリケーション タイプで動作させるには、大幅な明確化が必要です。CtrlC
.NET アプリケーションが独自のコンソール (Windows フォーム/WPF/Windows サービス/ASP.NET) を使用しない場合、基本的なフローは次のとおりです。
- Ctrl+でシグナルを送るプロセスのコンソールに、メインの .NET プロセスをアタッチしますC。
- Ctrlでシグナルの処理を無効にすることにより、メインの .NET プロセスが+Cイベントによって停止するのを防ぎます
SetConsoleCtrlHandler()
。
- 現在のコンソールのコンソールイベントを生成します
GenerateConsoleCtrlEvent()
(processGroupId
ゼロにする必要があります! 送信するコードの答えp.SessionId
は機能せず、正しくありません)。
- シグナルされたプロセスが応答するのを待ちます (例: プロセスが終了するのを待つ)
- 復元Ctrl+Cメイン プロセスによる処理とコンソールからの切断。
次のコード スニペットは、その方法を示しています。
Process p;
if (AttachConsole((uint)p.Id)) {
SetConsoleCtrlHandler(null, true);
try {
if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT,p.SessionId))
return false;
p.WaitForExit();
} finally {
SetConsoleCtrlHandler(null, false);
FreeConsole();
}
return true;
}
ここでSetConsoleCtrlHandler()
、 、FreeConsole()
、AttachConsole()
およびGenerateConsoleCtrlEvent()
はネイティブの WinAPI メソッドです。
internal const int CTRL_C_EVENT = 0;
[DllImport("kernel32.dll")]
internal static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
internal static extern bool FreeConsole();
[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
// Delegate type to be used as the Handler Routine for SCCH
delegate Boolean ConsoleCtrlDelegate(uint CtrlType);
対象のプロセスが応答するのを待つこと (通常はプロセスが終了するのを待つこと) が重要であることに注意してください。それ以外の場合、Ctrl+Cシグナルは現在のプロセスの入力キューに残り、 への 2 回目の呼び出しによって処理が復元されるとSetConsoleCtrlHandler()
、そのシグナルは対象プロセスではなく現在のプロセスを終了します。
.NET コンソール アプリケーションからCtrl+を送信する必要がある場合、事態はさらに複雑になります。この場合は返されるCため、上記のアプローチは機能しません(メイン コンソール アプリには既にコンソールがあります)。呼び出し前に呼び出すことは可能ですが、そうすると、元の .NET アプリ コンソールが失われ、ほとんどの場合、受け入れられません。AttachConsole()
false
FreeConsole()
AttachConsole()
この場合の私の解決策は次のとおりです。これは機能し、.NET メイン プロセス コンソールに副作用はありません。
- コマンド ライン引数からプロセス ID を受け取り、呼び出し
FreeConsole()
の前に独自のコンソールを失い、上記のコードでターゲット プロセスに+を送信する、小さなサポート .NET コンソール プログラムを作成します。AttachConsole()
CtrlC
- メインの .NET コンソール プロセスは、別のコンソール プロセスにCtrl+を送信する必要があるときに、新しいプロセスでこのユーティリティを呼び出すだけです。C