いくつかのプロセスを終了したいのですが、各プロセスにデータを保存する機会を与え、ユーザーにファイルの保存について尋ね、さらに閉じるリクエストを無視したいと思います。
したがって、TerminateProcess
はプロセスを即座に強制終了するため、問題外です。別の方法は、SendMessage
/PostMessage
を使用してWM_CLOSE
メインウィンドウに、残念ながら、プロセスのウィンドウについては何も知りません。プロセスIDしか持っていないので、FindWindow
も役に立ちません。プロセスのメインウィンドウを見つける他の方法はありますか?
つまり:終了する方法はありますかanyプロセスをクリックします。 タスクの終了 "? (「プロセスの終了」ではありません)
EnumWindows プロセス内のすべてのトップレベルウィンドウを列挙します。 GetWindowThreadProcessId は、各スレッドのプロセスとIDを取得します。
これで、GUIアプリケーションを適切に閉じるのに十分な情報が得られました。
WM_CLOSE
メッセージは、閉じたいウィンドウに送信できます。多くのウィンドウは、WM_CLOSE
を処理してドキュメントを保存するようユーザーに促します。PostThreadMessage
を使用して、検出されたスレッドにWM_QUIT
メッセージを送信して、メッセージループを終了できます。
ユーザーコードは、別のアプリまたはスレッドからウィンドウにDestroyWindow
を呼び出すことを許可されていません...アプリがWM_CLOSE
またはWM_QUIT
リクエストに応答しない場合、TerminateProcess
土地。
アプリケーションプロセスとウィンドウを所有するプロセスが異なるため、これはコンソールアプリケーションを閉じません。
Windowsでコンソールアプリケーションを正常に終了する実際の方法はありません。何らかの優雅なクローズメカニズムをサポートする必要があります。
Win32 APIについてはあまりよくわかりませんが、taskkill
コマンドライン関数をシェルで実行できます。
taskkill /?
taskkill /pid 1230
taskkill /im notepad.exe
/ fスイッチは強制終了しますが、使用しない場合は終了信号を送信するだけなので、アプリケーションは正常に終了します。
MSKB Q178893 Win32でアプリケーションを「クリーンに」終了する方法 を参照してください。
Chris Becke に追加するには、コンソールプロセスを正常に終了することについて回答します。
AttachConsole() コンソールアプリケーションにアタッチして、コントロールブレークイベントを送信します。 CTRL+C コマンドプロンプトで。
GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT、processID)を使用します。
この制御イベントは、正常な終了のためにコンソールアプリケーションで処理する必要があります。
EndTask API関数を使用します。これは、タスクマネージャーで使用されるのと同じ機能です。
BOOL EndTask(
HWND hWnd,
BOOL fShutDown,
BOOL fForce
);
http://msdn.Microsoft.com/en-us/library/ms633492(VS.85).aspx
taskkill/im your_program.exeを使用して、アプリケーションに終了信号を送信できます。 WindowsメッセージキューへのWM_CLOSEをトリガーします。次のいずれかを使用できます https://msdn.Microsoft.com/en-us/library/windows/desktop/ms633573(v = vs.85).aspx または
https://docs.Microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmessage
メッセージを処理します。
同様の答えを参照してください Win32 APIのSIGTERMの送信/キャッチの類似