Why Does Closing a Console That Was Started with Allocconsole Cause My Whole Application to Exit? How to Change This Behavior

Why does closing a console that was started with AllocConsole cause my whole application to exit? Can I change this behavior?

Ah, yes, this is one of the caveats of using the Windows console subsystem. When the user closes the console window (regardless of how the console was allocated), all of the processes that are attached to the console are terminated. That behavior makes obvious sense for console applications (i.e., those that specifically target the console subsystem, as opposed to standard Windows applications), but it can be a major pain in cases like yours.

The only workaround that I know of is to use the SetConsoleCtrlHandler function, which allows you to register a handler function for Ctrl+C and Ctrl+Break signals, as well as system events like the user closing the console window, the user logging off, or the system shutting down. The documentation says that if you're only interested in ignoring these events, you can pass null for the first argument. For example:

[DllImport("kernel32")]
static extern bool SetConsoleCtrlHandler(HandlerRoutine HandlerRoutine, bool Add);

delegate bool HandlerRoutine(uint dwControlType);

static void Main()
{
AllocConsole();
SetConsoleCtrlHandler(null, true);
while (true) continue;
}

That works perfectly for Ctrl+C and Ctrl+Break signals (which would have otherwise caused your application to terminate as well), but it doesn't work for the one you're asking about, which is the CTRL_CLOSE_EVENT, generated by the system when the user closes the console window.

Honestly, I don't know how to prevent that. Even the sample in the SDK doesn't actually allow you to ignore the CTRL_CLOSE_EVENT. I tried it in a little test app, and it beeps when you close the window and prints the message, but the process still gets terminated.

Perhaps more worryingly, the documentation makes me think it is not possible to prevent this:

The system generates CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT signals when the user closes the console, logs off, or shuts down the system so that the process has an opportunity to clean up before termination. Console functions, or any C run-time functions that call console functions, may not work reliably during processing of any of the three signals mentioned previously. The reason is that some or all of the internal console cleanup routines may have been called before executing the process signal handler.

It's that last sentence that catches my eye. If the console subsystem starts cleaning up after itself immediately in response to the user attempting to close the window, it may not be possible to halt it after the fact.

(At least now you understand the problem. Maybe someone else can come along with a solution!)

Why would a Console Application pops when reloading the Designer in Visual Studio 2015?

To display your control, WPF designer actually runs your code (not all of it, but still). So designer might execute your AllocConsole call, which leads to behavior you observe. To avoid this, do:

if (!DesignerProperties.GetIsInDesignMode(new DependencyObject())) {
AllocConsole();
Console.WriteLine("test");
}


Related Topics



Leave a reply



Submit