アプリケーションを実行して終了を待って、終了コードを返すプログラムは、
BOOL ExecuteApplication(const TCHAR* fileName, DWORD& exitCode)
{
STARTUPINFOA si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(si);
exitCode = -1;
BOOL bSuccess = ::CreateProcess(NULL, (LPTSTR)fileName, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
if (!bSuccess)
{
return FALSE;
}
::CloseHandle(pi.hThread);
if (::WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_OBJECT_0)
{
::CloseHandle(pi.hProcess);
return FALSE;
}
if (!::GetExitCodeProcess(pi.hProcess, &exitCode))
{
::CloseHandle(pi.hProcess);
return FALSE;
}
::CloseHandle(pi.hProcess);
return TRUE;
}
多分こんな感じになると思います。
が、例えばタスクマネージャから強制終了された場合、この exitCode の値はどうなるのでしょうか。
自分は ::WaitForSingleObject() か GetExitCodeProcess() でエラーが返されるだけだろうと思ってたんですが、実際に試してみると……
全部通りました。
なんでやねんヽ(`Д´)ノウワァン
ちょっと調べてみると、プロセスを強制終了させるためには ::TerminateProcess() を使うらしくて、ここで設定した終了コードが強制終了時の ::GetExitCodeProcess() の返り値になるようです。
なので、強制終了しても終了コードはちゃんと手に入るということになるのですが、じゃあ強制終了したかどうかを知る方法っていうのは無いのでしょうか?
実行するアプリケーションの動作を自分で書き換えられるのであれば、WinMain() を抜ける際にファイルやレジストリ、共有メモリ等に書き込むことによって判断が出来るのですが、任意のアプリケーションになるとそうもいかず……(~ヘ~;)ウーン
自分は、全てのアプリケーションの ::TerminateProcess() をフックして動作を書き換えてやるとか、WinMain() をフックしてその前後をちょこちょこ弄るぐらいしか思いつきませんでした……orz
どうするかなぁ……。