How do I create a C# app that decides itself whether to show as a console or windowed app?

Solution 1:

Make the app a regular windows app, and create a console on the fly if needed.

More details at this link (code below from there)

using System;
using System.Windows.Forms;

namespace WindowsApplication1 {
  static class Program {
    [STAThread]
    static void Main(string[] args) {
      if (args.Length > 0) {
        // Command line given, display console
        if ( !AttachConsole(-1) ) { // Attach to an parent process console
           AllocConsole(); // Alloc a new console
        }

        ConsoleMain(args);
      }
      else {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
      }
    }
    private static void ConsoleMain(string[] args) {
      Console.WriteLine("Command line = {0}", Environment.CommandLine);
      for (int ix = 0; ix < args.Length; ++ix)
        Console.WriteLine("Argument{0} = {1}", ix + 1, args[ix]);
      Console.ReadLine();
    }

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern bool AllocConsole();

    [System.Runtime.InteropServices.DllImport("kernel32.dll")]
    private static extern bool AttachConsole(int pid);

  }
}

Solution 2:

I basically do that the way depicted in Eric's answer, additionally I detach the console with FreeConsole and use the SendKeys command to get the command prompt back.

    [DllImport("kernel32.dll")]
    private static extern bool AllocConsole();

    [DllImport("kernel32.dll")]
    private static extern bool AttachConsole(int pid);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool FreeConsole();

    [STAThread]
    static void Main(string[] args)
    {
        if (args.Length > 0 && (args[0].Equals("/?") || args[0].Equals("/help", StringComparison.OrdinalIgnoreCase)))
        {
            // get console output
            if (!AttachConsole(-1))
                AllocConsole();

            ShowHelp(); // show help output with Console.WriteLine
            FreeConsole(); // detach console

            // get command prompt back
            System.Windows.Forms.SendKeys.SendWait("{ENTER}"); 

            return;
        }

        // normal winforms code
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());

    }