web-dev-qa-db-ja.com

CreateProcess()によって作成されたプロセスを終了する方法は?

CreateProcess()を使用してプロセスを作成しました。これはコードです:

STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
result = CreateProcess("C:\\AP\\DatabaseBase\\dbntsrv.exe", NULL, NULL, NULL, FALSE, 0, NULL, "C:\\ADP\\SQLBase", &si, &pi)

この特定のプロセスのHandleとprocessIdを取得するにはどうすればよいですか?そして最終的にそれを使用してこのプロセスを閉じますか?
ありがとうございました。

17
digvijay

構造体piで、次のようになります。

typedef struct _PROCESS_INFORMATION {
    HANDLE hProcess;
    HANDLE hThread;
    DWORD  dwProcessId;
    DWORD  dwThreadId;
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;

最初のパラメーターは、プロセスへのハンドルです。

そのハンドルを使用して、プロセスを終了できます。

BOOL WINAPI TerminateProcess(
    __in  HANDLE hProcess,
    __in  UINT uExitCode
);

hProcess [in]
終了するプロセスへのハンドル。

ハンドルには、PROCESS_TERMINATEアクセス権が必要です。詳細については、「プロセスのセキュリティとアクセス権」を参照してください。

ExitCode [in]
この呼び出しの結果として終了したプロセスとスレッドによって使用される終了コード。 GetExitCodeProcess関数を使用して、プロセスの終了値を取得します。 GetExitCodeThread関数を使用して、スレッドの終了値を取得します。

12
HardCoder

これは [〜#〜] msdn [〜#〜] で完全に説明されています:

結果がゼロ以外の場合(つまり、成功した場合)、ハンドルとプロセスIDを pi構造体 で取得します。

プロセスを強制終了するには、 TerminateProcess を使用できます。

1
Benoit

プロセスをきれいに閉じる

プロセスをクリーンに閉じるには、最初にクローズシグナルを送信する必要があります。

Win32でアプリケーションを「クリーンに」終了する方法

プロセスをどうしてもシャットダウンする必要がある場合は、次の手順に従ってください。

  1. シャットダウンするプロセスが所有するすべてのトップレベルウィンドウにWM_CLOSEを投稿します。多くのWindowsアプリケーションは、シャットダウンすることでこのメッセージに応答します。

    注:WM_CLOSEに対するコンソールアプリケーションの応答は、コントロールハンドラーがインストールされているかどうかによって異なります。

    EnumWindows()を使用して、ターゲットウィンドウへのハンドルを見つけます。コールバック関数で、WindowsのプロセスIDがシャットダウンするプロセスと一致するかどうかを確認します。これを行うには、GetWindowThreadProcessId()を呼び出します。一致を確立したら、PostMessage()またはSendMessageTimeout()を使用して、WM_CLOSEメッセージをウィンドウに送信します。

  2. WaitForSingleObject()を使用して、プロセスのハンドルを待ちます。 WM_CLOSEがアプリケーションをシャットダウンしない状況はたくさんあるので、必ずタイムアウト値で待機してください。ユーザーがWM_CLOSEメッセージに応答して作成されたダイアログボックスに応答できるように、タイムアウトを十分に長くすることを忘れないでください(WaitForSingleObject()またはSendMessageTimeout()のいずれかを使用)。

  3. 戻り値がWAIT_OBJECT_0の場合、アプリケーションはそれ自体を正常に閉じました。戻り値がWAIT_TIMEOUTの場合は、TerminateProcess()を使用してアプリケーションをシャットダウンする必要があります。

    注:WAIT_OBJECT_0またはWAIT_TIMEOUT以外のWaitForSingleObject()から戻り値を取得している場合は、GetLastError()を使用して原因を特定してください。

これらの手順に従うことで、アプリケーションをクリーンにシャットダウンするための最良の機会を与えることができます(IPCまたはユーザーの介入を除く)。

コードについてはこの回答を参照してください。

プロセスの終了

クリーンシャットダウンを気にしない場合は、TerminateProcess()を使用できます。ただし、TerminateProcess()は非同期であることに注意することが重要です。終了を開始し、すぐに戻ります。プロセスが終了したことを確認する必要がある場合は、プロセスへのハンドルを指定してWaitForSingleObject()関数を呼び出します。

TerminateProcess(pi.hProcess, 0);

// 500 ms timeout; use INFINITE for no timeout
const DWORD result = WaitForSingleObject(pi.hProcess, 500);
if (result == WAIT_OBJECT_0) {
    // Success
}
else {
    // Timed out or an error occurred
}

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);

閉じないで、終了するまで待つ

プロセスが自動的に終了する場合は、終了する代わりに、プロセスが終了するまで待つことができます。

WaitForSingleObject(pi.hProcess, INFINITE);

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
1
vll
STARTUPINFOA siStartupInfo;
PROCESS_INFORMATION piProcessInfo;
memset(&siStartupInfo, 0, sizeof(siStartupInfo));
memset(&piProcessInfo, 0, sizeof(piProcessInfo));
siStartupInfo.cb = sizeof(siStartupInfo);

DWORD dwExitCode = 0;
if (CreateProcess(prgName.c_str(),
                (LPSTR) parameters.c_str(), 
                0, 
                0, 
                false,
                CREATE_DEFAULT_ERROR_MODE, 
                0, 
                0,
                &siStartupInfo, 
                &piProcessInfo) != false)
{       
    dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, (time_in_ms));
}
else
{        
    return GetLastError(); //return error or do smething else
}

CloseHandle(piProcessInfo.hProcess);
CloseHandle(piProcessInfo.hThread);

piProcessInfo.hProcessはプロセスのハンドルです。

WaitForSingleObject:指定されたオブジェクトがシグナル状態になるか、タイムアウト間隔が経過するまで待機します。

その後 (time_in_ms)プロセスは終了します。

1
juergen d