Sending Ctrl+C event to a process launched using QProcess on Windows - c++

I have a dialog which acts as a configurator for a console application. The dialog’s job is to offer the user a set of widgets (which mirror the options supported by the console application) and when user clicks on the “Start” button, the dialog creates and starts a QProcess with the console application’s name and parameters based on the state of the widgets in the GUI. I am able to start the process successfully and everything works fine. However, when I want to kill the process, the console application needs to shutdown gracefully, meaning it has to close files, flush data, close devices etc., and then terminate.
I used QProcess::close(), this immediately kills the application and the app is unable to shutdown gracefully.
I have used the Win32 GenerateConsoleCtrlEvent(CTRL_C_EVENT, Q_PID::dwProcessId) to send an even to the same. I see that the above API returns a non-zero value (indicating a success, it would return 0 upon failure), but my process continues to run.
Can anyone help me with how I can signal the QProcess to shutdown gracefully? Or is there any other way to do this?

GenerateConsoleCtrlEvent takes a process group id, not a process id. You are likely feeding it a process id, since that's what QProcess provides.
QProcess doesn't support creation of a process group at the moment. You need to either start the process manually using winapi, or patch your copy of Qt to amend qtbase/src/corelib/io/qprocess[.h,.cpp,_win.cpp] to pass the CREATE_NEW_PROCESS_GROUP creation flag.
If you don't wish to tweak Qt itself, you can copy the qprocess files to your project, rename the class, and add the changes there.

Related

How is CLion terminating a process runing?

I am working on a TCP server that I'm developing on CLion under Windows 10.
I would like my program to be able to end properly, when I click on "stop" my program. I thought CLion was sending a signal, but after trying to catch them all, it looks like it does not.
So my question is, how does CLion stop running the program? Is it possible to detect it within the program?
Thank you in advance.
I found my answer here.
According to this link, signals are actually used :
Click this button to terminate the current process externally by means
of the standard shutdown script. Clicking the button once invokes soft
kill allowing the application to catch the SIGINT event and perform
graceful termination (on Windows, the Ctrl+C event is emulated). After
the button is clicked once, it is replaced with icon run tool window
kill indicating that subsequent click will lead to force termination
of the application, e.g. on Unix SIGKILL is sent.

What is the easiest way to handle window close event in WinAPI for the console application?

I'm writing a console multi-process application in c++ using WinAPI. So I have the Dispatcher(e.g. "Parent") and the Client(e.g. "Child") processes. Both processes are synchronized: they're using semaphors, events, mutexes and the pipe (all of them are standard WinAPI handles). Application stop when the user type the "exit" command. If the user do so, the dispatcher process notifies it's child, and then child releases its resources and makes another before-exit procedures to exit correctly. But there's a thing that bothers me: what will happen if the user press the window "close" button? If so, I should listen to close event and then perform my resource-releasing procedure. What is the easiest way to handle window close event?
Write a console handler routine that detects CTRL_CLOSE_EVENT (and CTRL_C_EVENT, if desired), and use SetConsoleCtrlHandler to add the handler routine to your process.
It isn't really different from the client process crashing or being terminated through Task Manager. You ought to be resilient to that as well. The ultimate signal you get for that in the parent process is that the client's process handle will be signaled.
Use WaitForMultipleObjects, along with those other handles, to detect this.

Hide console window in remote process

I have a windows application which invokes CreateProcess and then it exits. The process being invoked displays console and GUI windows at startup. I would like to hide the console window of the child process right when it starts.
More info:
Process is NOT started with DETACHED_PROCESS flag.
If injecting code with FreeConsole() to the remote process is the only way (I'm looking for a better one), is it not going to cause trouble with over-sensitive anti-viruses?
You can use the CREATE_NO_WINDOW flag to start a console application without a console window. It's not the same as it being hidden, but it sounds like it's what you want.

Win32 application with console output and without new window

I'd like to create a tool that can either act as command line (display some console output based on input parameters), or display a window, based on input parameters.
I'm using MSV2012 with C++, and it seems you have to 'choose' between console and window app.
I know the net is filled with samples which use AllocConsole() and redirect std::out, but it doesn't make it feel like a command line application : calling the exe from the windows console will open a new window with the console output...
Is there a way to have it use the current console window instead of allocating a new one?
If not possible, I'll make 2 applications instead, but that's a pity..
Someone else may have a more authoritative answer, but I don't believe it's supported.
The usual workaround is to create a Windows app, but have a command-line wrapper that launches it from the CLI (and provides a channel for communicating with the original console).
It's not technically supported but I found a good solution by getting a snapshot for the current process, finding the parent process, attaching to it's console if it's a console app or creating one with AllocConsole, redirecting the output, getting the thread of the parent process if it's cmd.exe and suspending it, resuming it just before I exit my app

What happens when you close a c++ console application

I guess the question says it all, but, what happens if someone closes a c++ console app? As in, clicks the "x" in the top corner. Does it instantly close? Does it throw some sort of exception? Is it undefined behavior?
Closing a c++ console app with the "x" in the top corner throws an CTRL_CLOSE_EVENT which you could catch and process if you set a control handler using the SetConsoleCtrlHandler function. In there you could override the close functionality and perform whatever you wished to do, and then optionally still perform the default behavior.
I imagine that the console process just gets unceremoniously killed by the OS. If you want to trap this event and do something it looks like the SetConsoleCtrlHandler function is the way to do it.
See also:
How to handle a ctrl-break signal in a command line interface
Console Event Handling
On Linux and other Unix systems, the console runs as a separate process. As you close the shell, it sends the SIGHUP signal to the currently active process or processes that are not executed in the background. If the programmer does not handle it, the process simply terminates. The same signal is sent if you close the SSH session with a terminal and an active process.
SIGBREAK is raised on Windows.