[閉じる]ボタンを使用してアプリケーションを強制終了することと、タスクマネージャーからプロセスを終了することの違いは何ですか?
[閉じる]ボタンを押すWM_CLOSE
とメッセージキューにメッセージが投稿されることは知っていますが、タスクマネージャー(またはKillboxやProcess Explorerなどの同様のアプリケーション)からプロセスを強制終了するとどうなるかわかりません。
[閉じる]ボタンを使用してアプリケーションを強制終了することと、タスクマネージャーからプロセスを終了することの違いは何ですか?
[閉じる]ボタンを押すWM_CLOSE
とメッセージキューにメッセージが投稿されることは知っていますが、タスクマネージャー(またはKillboxやProcess Explorerなどの同様のアプリケーション)からプロセスを強制終了するとどうなるかわかりません。
アプリケーションのウィンドウのタイトル バーにある [X] ボタンをクリックすると、ウィンドウにWM_CLOSE
メッセージが送信されます。これは「正常な」シャットダウンです。アプリケーションはメッセージを処理し、必要なクリーンアップ タスクを処理し、必要に応じてシャットダウンを拒否することもできます (メッセージに応答して 0 を返すことにより)。ウィンドウまたはアプリケーションが終了するというWM_CLOSE
単純な要求です。DestroyWindow
アプリケーション自体が関数を呼び出すまで、ウィンドウは破棄されません。
タスク マネージャーで [タスクの終了] ボタンを押すと、Windows は最初にアプリケーション (GUI アプリケーションの場合) にWM_CLOSE
メッセージを送信しようとします。つまり、最初に適切に要求し、アプリが正常に終了する機会を与えます。*
その最初のメッセージに応答して閉じることができなかった場合、タスク マネージャーは関数WM_CLOSE
を呼び出してフォローアップします。この関数は、アプリに許可を求めることなく、アプリケーションのプロセスとそのすべてのスレッドを強制的に終了するため、少し異なります。これは何かを閉じるための非常に厳しい方法であり、アプリケーションがハングしてメッセージに応答しなくなった場合など、最後の手段として使用する必要があります。TerminateProcess
TerminateProcess
プロセスのユーザーモード部分をメモリから実質的にリッピングし、無条件に終了させる非常に低レベルの関数です。呼び出しTerminateProcess
は、クローズ通知やDLL_PROCESS_DETACH
. アプリケーションには終了を拒否する機能がなく、への呼び出しをキャッチ/トラップ/フックする方法がありませんTerminateProcess
。プロセス内のすべてのユーザー モード コードは、完全に実行を停止します。これは非常に不潔なシャットダウン手順であり、コンピュータの電源プラグを壁から引き抜くようなものです。
*これは、タスク マネージャーの [アプリケーション] タブを使用してアプリケーションを強制終了した場合にのみ当てはまることに注意してください。「プロセス」タブを使用する場合、このステップはスキップされ、TerminateProcess
関数はすぐに呼び出されます。この違いは、それぞれのボタンのキャプションに反映されています。「アプリケーション」タブの場合、ボタンには「タスクの終了」というラベルが付けられています。「プロセス」タブの場合、ボタンには「プロセスの終了」というラベルが付いています。
でプロセスをWM_CLOSE
強制終了すると、メッセージでプロセスにシグナルが送信され、ターゲットがメッセージを処理して正常に終了できるようになります。あるいは、プロセスはWM_CLOSE
ハンドラーで終了しないことを選択できます。
タスクマネージャーを介してプロセスを強制終了すると、はるかに厳しいTerminateProcessを使用して強制終了します。
TerminateProcess関数は、プロセスを無条件に終了させるために使用されます。ExitProcessではなくTerminateProcessを使用すると、ダイナミックリンクライブラリ(DLL)によって維持されるグローバルデータの状態が損なわれる可能性があります。
この関数は、プロセス内のすべてのスレッドの実行を停止し、保留中のすべてのI/Oのキャンセルを要求します。終了したプロセスは、保留中のすべてのI/Oが完了するかキャンセルされるまで終了できません。プロセスが終了しても、プロセスに対して開いているハンドルを持つすべてのプロセスがそれらのハンドルを解放するまで、そのカーネルオブジェクトは破棄されません。
TerminateProcessは非同期です。終了を開始し、すぐに戻ります。プロセスが終了したことを確認する必要がある場合は、プロセスへのハンドルを指定してWaitForSingleObject関数を呼び出します。プロセスは、それ自体が終了するのを防ぐことはできません。
[閉じる]ボタンを使用してアプリケーションを閉じると、必要な終了タスクがあれば、アプリケーションに実行させることができます。タスクマネージャーからプロセスを強制終了した場合、アプリケーションがそれらのタスクを実行する機会はありません。通知せずにアプリケーションを終了するだけです。