QProcess::terminate can not stop Windows console application with SetConsoleCtrlHandler
I try to control Windows non-Qt console application from Qt desktop application.
Qt documentation says, that on Windows QProcess::terminate posts WM_CLOSE message. MSDN says that WM_CLOSE message is translated to CTRL_CLOSE_EVENT for console application.
So, in console application I call WinAPI function SetConsoleCtrlHandler, after that the application successfully intercept events like CTRL-C press (CTRL_C_EVENT) and Alt-F4 press (CTRL_CLOSE_EVENT).
From Qt application I successfully start console application using QProcess. Then I wait for application started using waitForStarted and try to gentle finish him using QProcess::terminate method, but nothing happens. In the same time QProcess kill works as expected.
What should I change in the console application or Qt application to receive event from QProcess::terminate?
More info: on WinXP I can intercept CTRL_CLOSE_EVENT in console app, on Win7 can not. Microsoft changed behavior for CTRL_CLOSE_EVENT somewhere between WinXP and Vista.
Nevertheless even on WinXP console application did not receive CTRL_CLOSE_EVENT when Qt application call QProcess::terminate. Any idea?
If terminate() doesn't work, try kill() ;-)
It probably is the same as kill(), on Win32, but you can also try:
Of course I can use QThread::kill, but I need a chance to do some sort of a clean up in the console application.
Then terminating or killing the process from outside probably is not the way to go. Instead, you should make your Console application read messages from its STDIN, so you can send commands to it. QProcess can write to the child process' STDIN, simply use the write() method. This way, you could send some string like, for example, "CMD_EXIT", which tells the application that it should shutdown "properly" by itself as soon as possible.
Console applications do NOT normally run an event loop to process Window messages. That's why sending a WM_CLOSE usually doesn't do anything. Therefore the Qt documentation explicitly states:
[quote]Console applications on Windows that do not run an event loop, or whose event loop does not handle the WM_CLOSE message, can only be terminated by calling kill().[/quote]
BTW: Killing an application via terminate() is never "safe", as the app may very well ignore the WM_CLOSE message - intentionally or by malfunction. You should send a kill(), if it doesn't terminate within a few seconds...