how to terminate a process created by CreateProcess()?

31,354

Solution 1

In the struct pi you get:

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

The first parameter is the handle to the process.

You can use that handle to end the process:

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

hProcess [in]
A handle to the process to be terminated.

The handle must have the PROCESS_TERMINATE access right. For more information, see Process Security and Access Rights.

uExitCode [in]
The exit code to be used by the process and threads terminated as a result of this call. Use the GetExitCodeProcess function to retrieve a process's exit value. Use the GetExitCodeThread function to retrieve a thread's exit value.

Solution 2

A handle to the process is returned in the PROCESS_INFORMATION structure, pi variable.

The TerminateProcess() function can be used to terminate the process. However, you should consider why you need to kill the process and why a graceful shutdown is not possible.

Note you need to set the cb member of si before calling CreateProcess():

si.cb = sizeof(STARTUPINFO);

EDIT:

To suppress the console window specify CREATE_NO_WINDOW, as the creation flag (the sixth argument) in the CreateProcess() call.

EDIT (2):

To suppress the window try setting following members of STARTUPINFO structure prior to calling CreateProcess():

STARTUPINFO si = {0};
si.cb          = sizeof(STARTUPINFO);
si.dwFlags     = STARTF_USESHOWWINDOW;
si.wShowWindow = FALSE;

Solution 3

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:

  1. 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.

  1. 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.

  2. 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);

Solution 4

This is explained thoroughly in MSDN:

If result is non-zero (which means that it succeeded) you will get the handle and processid in the pi structure.

In order to kill the process you can use TerminateProcess

Share:
31,354
digvijay
Author by

digvijay

Updated on April 17, 2021

Comments

  • digvijay
    digvijay about 3 years

    I have created a process using CreateProcess(). This is the code:

    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)
    

    How can I get the Handle and processId of this specific process? And eventually use it to close this process?
    Thank You.

  • Alexey Frunze
    Alexey Frunze about 12 years
    +1 for graceful shutdown. The process can be instructed to shutdown by e.g. sending a message to it.