2

Working Environment: c++, windows

I want to store all pids (not process name), then kill processes programatically when I want to kill. I know I can kill a process by using system("taskkill /pid xxxx"), but I want to know better/best way to kill a process by pid. What is the best way to kill a process and why?

joe_chip
  • 2,468
  • 1
  • 12
  • 23
lll
  • 302
  • 3
  • 13
  • 3
    *What is the best way to kill a process and why?* send it a message and politely ask it to shut down when it is safe to do so. Much less room for undesirable side effects. – user4581301 Apr 12 '19 at 00:09

2 Answers2

2

Fortunately, killing it once you have a PID is pretty easy.

  1. do OpenProcess to get a process handle from the PID
    • be sure to specify the PROCESS_TERMINATE right.
  2. do TerminateProcess to kill the process
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • should i check if process is running before I terminate the process? What If the process does not exist? – lll Apr 12 '19 at 00:55
  • @lll: If the process doesn't exist, your call to `OpenProcess` will fail, and return `NULL`. You can detect that and print out an error message, or you can just ignore the fact that it's `NULL`, and pass it to `TerminateProcess` anyway (and then it'll fail too, of course). – Jerry Coffin Apr 12 '19 at 01:12
  • This is not the same as taskkill.exe without the `/F` option, which sends `WM_CLOSE` to an application's top-level and message-only windows (discovered by enumerating all WindowStations and Desktops in the session and mapping a window to a process via `GetWindowThreadProcessId`). Sending the close message allows a process to exit gracefully. First try it graceful, and if the app is still running after a timeout, then fall back on `OpenProcess` and `TerminateProcess`. – Eryk Sun Apr 12 '19 at 10:33
  • If a process has no windows, then it may be a console process, but not the lead process in the console session (i.e. not effective owner of the console window; conhost.exe is the real owner, but the system tells a white lie). You can try `AttachConsole(pid)`, and if it success call `SetConsoleCtrlHandler` to ignore control events in your process and `GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0)` to send Ctrl+Break to all processes attached to the console. Killing all processes attached to the console is dubious, but not more so than what taskkill.exe already does for the lead console process. – Eryk Sun Apr 12 '19 at 10:44
1

You can kill the process using OpenProcess() and TerminateProcess(). The code will look something like this :

HANDLE handle = OpenProcess(PROCESS_TERMINATE, FALSE, ProcessID);
if (NULL != handle) {   
    TerminateProcess(handle, 0);
    CloseHandle(handle);
}

For the inconvenience of the use of system("taskkill /pid xxxx"), I invite you to read this post. A large number of answers have been given to explain why not to use this expression.

  • Slow: It has to jump through lots of unnecessary Windows code and a separate program for a simple operation.

  • Not portable: Dependent on the pause program.

  • Not good style: Making a System call should only be done when really necessary

Maxime
  • 838
  • 6
  • 18