Keeping console windows open
A quick explanation on how to set up your C# console application to keep its window open when launched from the Windows GUI

I was recently working on a (Windows) console application that would be launched in two main ways:

  1. Some users would run the exe from within an existing console session (such as Windows Terminal).
  2. Other users would run the exe by double-clicking it from their desktop, or from Windows Explorer.

The problem here is that instances launched in scenario #2 will immediately close when they have finished running, leaving no time for the user to view the output. We could add a traditional Press any key to continue... pause to them, but then this introduces a new problem: instances launched in scenario #1 will also have that pause, which is totally unnecessary. So, what we want is to add a pause for scenario #2, but not for scenario #1.

Luckily, there is a solution that gives us the best of both worlds! We can use the native GetConsoleProcessList API to list which processes are attached to the current console. In scenario #1, there will be at least 2 - our app, and the shell (such as powershell / cmd / etc.). In scenario #2, there will only be 1 - our app. We can then add our "pause" / "press any key" logic to only run in scenario #2.

Here is an example of how that code could look:

public static class ConsoleHelper
{
    public static void PauseIfOnlyProcessAttachedToConsole()
    {
        var processList = new uint[1];
        var processCount = NativeMethods.GetConsoleProcessList(processList, 1);
        if (processCount == 1)
        {
            Console.WriteLine();
            Console.Write("Press any key to continue . . . ");
            Console.ReadKey();
        }
    }

    private static class NativeMethods
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern uint GetConsoleProcessList(uint[] processList, uint processCount);
    }
}

Posted by Matthew King on 31 August 2023
Permission is granted to use all code snippets under CC BY-SA 3.0 (just like StackOverflow), or the MIT license - your choice!
If you enjoyed this post, and you want to show your appreciation, you can buy me a beverage on Ko-fi or Stripe