PDA

View Full Version : Can't send a Ctrl-C to a QProcess (Win32)



Starbuck
12th December 2010, 16:09
I create a Process class from QProcess to run MEncoder.

Everything's fine and I can abort the process with kill() method.

However in Win32 CLI, running MENcoder and typing Ctrl-C make MEncoder to stop smoothly.

Therefore I try to stop smoothly writing Ctrl-C (0x03) with:


class Process : QProcess
{
...
char ctrlC = 0x03;
write( &ctrlC );
...

And it just does nothing :(

wysota
12th December 2010, 17:26
It's not how it works. Ctrl+C when issued to the terminal of the process (not to its standard input) causes the operating system to send a SIGTERM signal to the process. So what you have to do is to use QProcess API to send a SIGTERM signal to your child process - use terminate() instead of kill(). The latter sends SIGKILL instead of SIGTERM.

Starbuck
12th December 2010, 18:47
Thanks for replying, nevertheless, it isn't working exactly like you suggest:

with terminate() the process just continues... I guess the program expects a SIGINT (3) as Ctrl-C and Windows has no SIGINT support (taskklist /t ot /f).

Any other idea?

wysota
12th December 2010, 18:58
Sorry, yes, Ctrl+C is SIGINT. Nevertheless using terminate() is the way to go. Unfortunately console applications don't support being killed by terminate(). What you can do is try to send the SIGINT signal yourself to the other process using ::kill() (your system should support it).

hg
27th March 2014, 09:17
Sorry for the late entrance, but it would seem this is still a valid discussion. I have just solved the problem under Windows 7 with Qt5 by closing the stream to stdin of the child process. I.e. process->close() instead of process->terminate(). The child process was then gracefully able to shut down.

wysota
27th March 2014, 09:28
Maybe because your child program ends when it gets end of stream on its stdin. It's not the case for any program.

hg
27th March 2014, 11:49
My scenario works from command line, but not via QProcess, not even using close() as I suggested earlier. This is very curious, as there seem to be a way of signaling the console application (i.e node.exe in my case) to close, but it is not used by QProcess::terminate(). I have solved my particular problem by writing a shutdown command to stdin and reading it in the child process, but it is not a generic solution.

A similar discussion is found on qt-project: http://qt-project.org/forums/viewthread/28029

wysota
27th March 2014, 11:51
A well-behaved process should terminate itself when receiving SIGTERM which is what QProcess::terminate() sends.

yeye_olive
31st March 2014, 22:41
This reply comes a bit late.

It is unfortunate that Windows' API does not deal with GUI and console processes in a uniform way. The documentation of QProcess::terminate() clearly states that it only supports the former kind. In you case, I suggest -- for lack of a better solution -- that you rely on platform-specific API for console processes; the GenerateConsoleCtrlEvent (msdn.microsoft.com/en-us/library/windows/desktop/ms683155.aspx) function looks promising.