Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gracefully terminate a command line application on Windows

I'm creating a command-line application, which spawns a process (command defined by a user, usually an HTTP server) and when the application's job is done, I want to let the process know it should terminate.

In UNIX, I can do that by sending SIGTERM and if the process doesn't end, then I can kill it brutally by SIGKILL.

In Windows, I struggle to find an alternative to the SIGTERM scenario. I learned there's taskkill /PID XXXX (without /f!), but

  1. I found no information about what taskkill /PID XXXX does under the hood, hence I can't test it. I can't find how to handle whatever taskkill /PID XXXX sends on the process side.
  2. It doesn't seem to work with commands in cmd.exe. I tried to run a simple server process in one cmd.exe, get its PID and in another window to taskkill /PID XXXX it, but taskkill refused to do that: ERROR: The process with PID XXXX could not be terminated. Reason: This process can only be terminated forcefully (with /F option).

So my question is: How to inform a command-line process in Windows that it should terminate without forcefully terminating it? How to receive and act upon such message on the process-to-be-terminated side?

like image 903
Honza Javorek Avatar asked Feb 17 '17 16:02

Honza Javorek


People also ask

How do I gracefully kill a process in Windows?

You can send WM_CLOSE messages to any window you wish to close. Many windows handle WM_CLOSE to prompt the user to save documents. You can send a WM_QUIT message using PostThreadMessage to the discovered threads to cause the message loop to terminate.

Which command will terminate command line interface?

This command exits the command-line interface, terminating the current session.


2 Answers

GenerateConsoleCtrlEvent signals a console application as if the user had pressed Ctrl+C or Ctrl+Break. Console applications can ignore these signals (using SetContolCtrlHandler), but, by default, they just do an ExitProcess on themselves.

This is the same signal Windows uses when the user closes the console window, logs off, or shuts down.

like image 151
Adrian McCarthy Avatar answered Sep 17 '22 15:09

Adrian McCarthy


TaskKill uses PostMessage(hwnd, WM_CLOSE, 0, 0); (basically the same as pressing the X on a window) if the process has a visible window.

If you know the application is a console application you can use GenerateConsoleCtrlEvent instead.

like image 35
Anders Avatar answered Sep 20 '22 15:09

Anders