Using the Win32 API in Visual C++, I want to create a program under the Windows subsystem that allocates a console with AllocConsole and writes to it with WriteConsole. However, if the user closes the console, the process should keep running in the background. As it stands, I can't get that to happen. When X is pressed on the console title bar, the process exits.
Is there any particular way of doing this?
Thanks in advance!
The key is to respond to the Console Control Event that is raised when the user attempts to close the console. You can then call FreeConsole to detach your program from the console, and let the console be destroyed. That should keep your program running.
Additional info:
If the process is terminated when the HandlerRoutine exits, then my suggestion didn't work as expected. If that's the case, then you might have a problem. You can try hooking the SC_CLOSE system message, and do the FreeConsole there before passing the message on. That might work, although I don't know what it'll do if the user presses Ctrl+C or Ctrl+Break.
The problem is that the control handler exits the process. It might be that calling FreeConsole in the HandlerRoutine is too late.
Related
We have an old MFC-based C++ gui app (Visual Studio 6.0) which often does not terminate correctly. So I would like to be able to use a instruction like "abort();" to immediately end it.
However, the abort() instruction causes a dialog box to pop up, rather than ending immediately. Using "exit(int)" doesn't work.
Is there a way to eliminate the abort dialog, or is there a better termination method?
One obvious way to abort without anything else happening ahead of time would be for it to call the Windows ExitProcess function:
ExitProcess(exitCode);
If you want to kill it from some external program, you'd do that with TerminateProcess. To do that, you'll need a handle to the process, which typically means getting its process ID. If you're doing this from a program that spawned the one you want to kill, you'll probably get a handle to it when you create it. Otherwise, you'll probably need to use something like FindWindow to find its window, then GetWindowThreadProcessId to find the ID of that window's process. Once you have that, you call OpenProcess to get a handle, and finally TerminateProcess to actually kill it.
If it is a dialog box based app, then you can use EndDialog(IDOK) method.
Some programs pop "Save before exit?" message when terminating.
And I wonder if I can implement this with C++ console application.
So I tried some standard functions like signal and atexit.
But they only work when:
main() returns (atexit)
sending interrupt through Ctrl+C (on Windows, SIGINT)
an error occurs (SIGABRT)
So yeah, how? Is it only possible with GUI application?
In comments, you said:
I want exit events to happen when that 'X' button is pressed(On windows).
That's part of GUI I guess.
Than what kind of request is sent to program when the exit button of the console is pressed?
You can use SetConsoleCtrlHandler() to register a user defined callback function that receives a CTRL_CLOSE_EVENT notification when the console window is closed:
A signal that the system sends to all processes attached to a console when the user closes the console (either by clicking Close on the console window's window menu, or by clicking the End Task button command from Task Manager).
I have just got this problem for a few days. Before, I've always thought that letting the program exit by returning from main and clicking close the console window is the same way to end the program.
However, I've found that they are different. Since my program opens a camera which is an object. And closing the console windows does not destroy or clean up the object. So the next time I have error to open the camera again
I just need a confirm if this is true?
Then why only until now I can see the problem?
Closing a console window in Windows, kills the running program (or stack of running programs). Unless it has registered a handler for this event, it gets no chance to clean up. If you want solution, register a handler.
Hm, consulting the documentation, wait a few secs…
OK, look up SetConsoleCtrlHandler.
Closing a running console application will kill the process, not giving you the chance for any clean up code. I guess you could hook a windows message loop to trap the WM_CLOSE message and do proper cleanup, but at the end of the day, you just shouldn't kill the 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.
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.