web-dev-qa-db-ja.com

プロセスを正常に終了する方法は?

いくつかのプロセスを終了したいのですが、各プロセスにデータを保存する機会を与え、ユーザーにファイルの保存について尋ね、さらに閉じるリクエストを無視したいと思います。

したがって、TerminateProcessはプロセスを即座に強制終了するため、問題外です。別の方法は、SendMessage/PostMessageを使用してWM_CLOSEメインウィンドウに、残念ながら、プロセスのウィンドウについては何も知りません。プロセスIDしか持っていないので、FindWindowも役に立ちません。プロセスのメインウィンドウを見つける他の方法はありますか?

つまり:終了する方法はありますかanyプロセスをクリックします。 タスクの終了 "? (「プロセスの終了」ではありません)

36
Daniel Rikowski

EnumWindows プロセス内のすべてのトップレベルウィンドウを列挙します。 GetWindowThreadProcessId は、各スレッドのプロセスとIDを取得します。

これで、GUIアプリケーションを適切に閉じるのに十分な情報が得られました。

WM_CLOSEメッセージは、閉じたいウィンドウに送信できます。多くのウィンドウは、WM_CLOSEを処理してドキュメントを保存するようユーザーに促します。PostThreadMessageを使用して、検出されたスレッドにWM_QUITメッセージを送信して、メッセージループを終了できます。

ユーザーコードは、別のアプリまたはスレッドからウィンドウにDestroyWindowを呼び出すことを許可されていません...アプリがWM_CLOSEまたはWM_QUITリクエストに応答しない場合、TerminateProcess土地。

アプリケーションプロセスとウィンドウを所有するプロセスが異なるため、これはコンソールアプリケーションを閉じません。

Windowsでコンソールアプリケーションを正常に終了する実際の方法はありません。何らかの優雅なクローズメカニズムをサポートする必要があります。

25
Chris Becke

Win32 APIについてはあまりよくわかりませんが、taskkillコマンドライン関数をシェルで実行できます。

taskkill /?
taskkill /pid 1230
taskkill /im notepad.exe

/ fスイッチは強制終了しますが、使用しない場合は終了信号を送信するだけなので、アプリケーションは正常に終了します。

15
Andy E
13

Chris Becke に追加するには、コンソールプロセスを正常に終了することについて回答します。

AttachConsole() コンソールアプリケーションにアタッチして、コントロールブレークイベントを送信します。 CTRL+C コマンドプロンプトで。

GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT、processID)を使用します。

この制御イベントは、正常な終了のためにコンソールアプリケーションで処理する必要があります。

3
T.s. Arun

EndTask API関数を使用します。これは、タスクマネージャーで使用されるのと同じ機能です。

BOOL EndTask(      
    HWND hWnd,
    BOOL fShutDown,
    BOOL fForce
);

http://msdn.Microsoft.com/en-us/library/ms633492(VS.85).aspx

1
Jason

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の送信/キャッチの類似

0
amilamad