0

I have a WinForm project that opens a console for debugging. This is very common for game development in C++. When I try this in C#, I'm not getting the desired result. I think it's because I need to set the standard output to the console.

I was following this: http://vbcity.com/blogs/jatkinson/archive/2010/02/17/windows-interop-inside-kernel32-part-1-allocconsole-amp-createhardlink.aspx

While it used Console.WriteLine(), it skips setting the output handle to the console. How can I set that in C#?

My code:

namespace MVS
{
    public partial class frmMVS : Form
    {
        [DllImport("kernel32")]
        static extern bool AllocConsole();

        public frmMVS()
        {
            InitializeComponent(); 

            AllocConsole(); 
            Console.WriteLine("Hello World!");
        } 
    }
}

Current attempt (though nothing is outputted to the console): Source: No console output when using AllocConsole and target architecture x86

namespace MVS
{
    public partial class frmMVS : Form
    { 
        public frmMVS()
        {
            InitializeComponent();

            CreateConsole();

            Console.WriteLine("Hello World!");
        }

        public static void CreateConsole()
        {
            AllocConsole();

            // stdout's handle seems to always be equal to 7
            IntPtr defaultStdout = new IntPtr(7);
            IntPtr currentStdout = GetStdHandle(StdOutputHandle);

            if (currentStdout != defaultStdout)
                // reset stdout
                SetStdHandle(StdOutputHandle, defaultStdout);

            // reopen stdout
            TextWriter writer = new StreamWriter(Console.OpenStandardOutput())
            { AutoFlush = true };
            Console.SetOut(writer);
        }

        // P/Invoke required:
        private const UInt32 StdOutputHandle = 0xFFFFFFF5;
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetStdHandle(UInt32 nStdHandle);
        [DllImport("kernel32.dll")]
        private static extern void SetStdHandle(UInt32 nStdHandle, IntPtr handle);
        [DllImport("kernel32")]
        static extern bool AllocConsole();
    }
}

Current solution: For now, my current solution is to remove all this interop code and set the Output Type to Console Application from my Windows application. This allows both the form and console to work side by side. Because users running the application will also see the console, remember to set the Output Type back to Windows before publishing. Since the console is used for debugging anyway, this seems like an easy solution for its purpose. I don't know how it's going to affect the solution as I develop, so an alternative is still of interest.

slugster
  • 49,403
  • 14
  • 95
  • 145
Phil
  • 137
  • 2
  • 10
  • might this help you https://stackoverflow.com/questions/15604014/no-console-output-when-using-allocconsole-and-target-architecture-x86 ?? – Ofir Winegarten Aug 06 '17 at 17:44
  • Apologies if I misunderstand but have you tried `Debug.WriteLine()`? – Christopher Lake Aug 06 '17 at 19:57
  • Yes, this doesn't show any output either. In fact, the console window doesn't open either. When I have the console window open, it still does not display any output. – Phil Aug 06 '17 at 20:01
  • For games, no. It's a mess to find using VS. I need the console window. My solution above is temporary but it works for now until I find a related response. – Phil Aug 06 '17 at 20:12

1 Answers1

0

For debugging purposes, this simple solution ended up being efficient for me:

In your Windows Forms project, 1) Go to Project -> My Project's Properties -> Set Output Type from 'Windows Application' to 'Console Application'. 2) Save, and you're done.

Now you can output to the console for debugging as you usually would using Console.WriteLine().

Note: Be sure to switch the Output Type back to 'Windows Application' prior to publishing, else the user will see the console window.

Phil
  • 137
  • 2
  • 10
  • That's not cutting it. I'm struggling with the same problem for quite a while and found two working solutions. Both of them somehow stopped working after some time though. The thing is you can't just change the project type if you're developing i.e. a WPF application. Moreover you want to show console and the WPF window - which does not work that easy. – SharpShade Sep 27 '17 at 02:01