CreateProcessで起動したプロセスを安全に終了させるには、
皆さん、どのような手法をとっていますか?
1.ハンドル取って、WM_CLOSEをPostMessage
2.TerminateThread(こわい・・・(T-T)
3.EnumThreadWindowsによる終了
どのやり方も、今ひとつ完璧な方法(コードの書き方)が良く分かりません。
これなら安全という手法がありましたら、詳細を教えて頂きたく。
よろしくです。
3択なら、これ
> 1.ハンドル取って、WM_CLOSEをPostMessage
ただし、どのウィンドウに Post するかによっては終了しないことも考えられるので、理想的なのは4つ目
4.終了させられる側のプログラムに、そのための受け入れ口を作っておく
御意見ありがとうございます。
>4.終了させられる側のプログラムに、そのための受け入れ口を作っておく
というのは、WM_CLOSEでなく、WM_USER+???の受け口を作成して、そのメッセージをPostしてあげる、ってことですよね?
ついでに質問させてください。
> 1.ハンドル取って、WM_CLOSEをPostMessage
の場合、
・対象ウィンドウのハンドルは、FindWindowで取得するのが好ましいですか?
それとも、その他の方法?
・ウィンドウを持たないプロセスを起動した場合(バックグランドアプリ etc.)、
どのような手法でそのプロセスは終了できますか?
CreateProcessを使うんですよね?
MSDNヘルプに、プロセスをシャットダウンするにはという、解説があるんですが
また、成功時には、PROCESS_INFORMATIONに値が入っていません?
>> 4.終了させられる側のプログラムに、そのための受け入れ口を作っておく
> というのは、WM_CLOSEでなく、WM_USER+???の受け口を作成して、そのメッセージをPostしてあげる、ってことですよね?
はい。厳密に言えば WM_APP + ??? ですが。
全てのプロセスが、トップレベルウィンドウに WM_CLOSE を投げられたら終了するとは限りませんからね。
> ・対象ウィンドウのハンドルは、FindWindowで取得するのが好ましいですか?
FindWindow で取得しようが EnumWindows で取得しようがその他の関数で取得しようが、そのウィンドウに WM_CLOSE を投げたらプロセスが終了するという保証が無い以上は同じことです。
逆に言えば、汎用的なものではなく、特定のアプリだけを終了させたい場合、かつ、ウィンドウクラス名がわかっていて、そのウィンドウに WM_CLOSE を投げればプロセスが終了するという検証ができている場合は、FindWindow がいいでしょう。
> ・ウィンドウを持たないプロセスを起動した場合(バックグランドアプリ etc.)、
> どのような手法でそのプロセスは終了できますか?
そのプロセスが外部からのメッセージ受け入れ口を用意していないならば、何らかの方法でメインスレッドを特定して、PostThreadMessage で WM_QUIT を投げるとか。
強引なので、TerminateProcess と、危険度では大して変わらない気がしますね。
タスクトレイ常駐アプリだったら、タスクトレイからのメッセージを受けるためのウィンドウがどこかにあるはずなので、それを突き止めて消すとか。
> MSDNヘルプに、プロセスをシャットダウンするにはという、解説があるんですが
ExitProcess は安全に終了できますが、外部から呼び出すことはできません。
自プロセスを終了させたいときに使うものです。
…DLL インジェクションして ExitProcess なんてしない限りは。
同意のない殺プロセスに安全性などないということで終了
同意殺プロセスについてはこのあたり(↑)のレス参照
シャノンさん
詳細な御説明ありがとうございます。
様々なケースで、どういった手法が安全なプロセスの終了方法なのか、
確認させて頂きました。
ありがとうございました。
ツイート | ![]() |