CreateProcess()で起動したアプリを終了させる。

CreateProcess()で起動したアプリを終了させるには
TerminateProcess()を使えば簡単に終了させる事が出来ますが
この関数は強制終了させるのでメモリリーク等が発生し危険です。
安全に終了させるには起動したアプリのトップレベルのウィンドウに
WM_CLOSEを送って終了させます。
それにはトップレベルウィンドウのハンドルを取得する必要がありますが
プロセスハンドル・プロセスIDから直接ウィンドウのハンドルを取得する事は出来ません。
しかしウィンドウのハンドルからそれを起動したプロセスのIDが分かるので
全てのウィンドウハンドルを取得しプロセスIDを調べ、CreateProcess()で取得した
プロセスIDと比較し一致すれば、それが起動したアプリのウィンドウハンドルになります。


コールバック関数。この関数はグローバルでなければなりません。

// ウィンドウハンドルを取得しアプリを終了させる。
BOOL CALLBACK EnumWndProc( HWND hWnd, LPARAM lParam )
{
    PROCESS_INFORMATION* pi = ( PROCESS_INFORMATION* )lParam;

    // ウインドウを作成したプロセスを取得。
    DWORD lpdwProcessId = 0;
    GetWindowThreadProcessId( hWnd, &lpdwProcessId );

    // CreateProcessで起動したアプリのプロセスIDとメインウィンドウを
    // 作成したプロセスIDが同じ場合、起動したアプリを終了させる。
    if (GetWindow( hWnd, GW_OWNER ) == NULL)
    {
        if (pi->dwProcessId == lpdwProcessId)
            PostMessage( hWnd, WM_CLOSE, 0, 0L );
    }
    return TRUE;
}

使用例。

// メモ帳の起動。
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof( STARTUPINFO ));
si.cb          = sizeof( STARTUPINFO );
si.dwFlags     = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
CreateProcess( NULL, _T("notepad.exe"), NULL, NULL, FALSE,0, NULL, NULL, &si, &pi);
CloseHandle( pi.hThread );

AfxMessageBox( _T("メモ帳を終了させます。"));

// コールバック関数の呼び出し。全てのウィンドウを取得するまで繰り返し呼ばれます。
EnumWindows( EnumWndProc, (LPARAM)&pi );

CloseHandle( pi.hProcess );

[ 戻る ]