Closing the process cleanly
To close the process cleanly, you should send a close signal first:
How To Terminate an Application "Cleanly" in Win32.
If you absolutely must shut down a process, follow these steps:
- Post a WM_CLOSE to all Top-Level windows owned by the process that you want to shut down. Many Windows applications respond to this message by shutting down.
NOTE: A console application's response to WM_CLOSE depends on whether or not it has installed a control handler.
Use EnumWindows() to find the handles to your target windows. In your callback function, check to see if the windows' process ID matches the process you want to shut down. You can do this by calling GetWindowThreadProcessId(). Once you have established a match, use PostMessage() or SendMessageTimeout() to post the WM_CLOSE message to the window.
Use WaitForSingleObject() to wait for the handle of the process. Make sure you wait with a timeout value, because there are many situations in which the WM_CLOSE will not shut down the application. Remember to make the timeout long enough (either with WaitForSingleObject(), or with SendMessageTimeout()) so that a user can respond to any dialog boxes that were created in response to the WM_CLOSE message.
If the return value is WAIT_OBJECT_0, then the application closed itself down cleanly. If the return value is WAIT_TIMEOUT, then you must use TerminateProcess() to shutdown the application.
NOTE: If you are getting a return value from WaitForSingleObject() other then WAIT_OBJECT_0 or WAIT_TIMEOUT, use GetLastError() to determine the cause.
By following these steps, you give the application the best possible chance to shutdown cleanly (aside from IPC or user-intervention).
See this answer for code.
Terminating the process
If you don't care about clean shutdown, you can use TerminateProcess()
. However, it is important to note that TerminateProcess()
is asynchronous; it initiates termination and returns immediately. If you have to be sure the process has terminated, call the WaitForSingleObject()
function with a handle to the process.
Note: Access rights PROCESS_TERMINATE
and SYNCHRONIZE
are required.
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);
Not closing, just wait until finished
If the process will finish on its own, instead of terminating you can wait until it has finished.
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);