Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AllocConsole not printing when in Visual Studio

I want to create a console window and print some info on it when debugging my program. VS 2010 does not give me the option of setting different Output types for my program depending on whether its in debug or release mode, so I resorted to creating a Console window manually like so:

[DllImport("kernel32.dll")]
public static extern Int32 AllocConsole();

static void Main()
{
#if DEBUG
    AllocConsole();
#endif
....

That pops open a console window, but nothing gets written to it. I tried a bunch of other pinvoke (AttachConsole etc...) that did nothing. Then I finally tried running the application outside of Visual Studio, and the Console Window worked. Apparently Visual Studio is eating up all my Console.WriteLines!

How can I fix this?

like image 911
Bob Coder Avatar asked Aug 04 '26 22:08

Bob Coder


1 Answers

Having encountered the same issue, here is some code that appears to restore console output for me after the call to AllocConsole:

    private static void OverrideRedirection()
    {
        var hOut = GetStdHandle(STD_OUTPUT_HANDLE);
        var hRealOut = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, FileShare.Write, IntPtr.Zero, FileMode.OpenOrCreate, 0, IntPtr.Zero);
        if (hRealOut != hOut)
        {
            SetStdHandle(STD_OUTPUT_HANDLE, hRealOut);
            Console.SetOut(new StreamWriter(Console.OpenStandardOutput(), Console.OutputEncoding) { AutoFlush = true });
        }
    }

P/Invokes as follows:

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr GetStdHandle(int nStdHandle);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool SetStdHandle(int nStdHandle, IntPtr hHandle);

    public const int STD_OUTPUT_HANDLE = -11;
    public const int STD_INPUT_HANDLE  = -10;
    public const int STD_ERROR_HANDLE  = -12;

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr CreateFile([MarshalAs(UnmanagedType.LPTStr)] string         filename,
                                           [MarshalAs(UnmanagedType.U4)]     uint           access,
                                           [MarshalAs(UnmanagedType.U4)]     FileShare      share,
                                                                             IntPtr         securityAttributes,
                                           [MarshalAs(UnmanagedType.U4)]     FileMode       creationDisposition,
                                           [MarshalAs(UnmanagedType.U4)]     FileAttributes flagsAndAttributes,
                                                                             IntPtr         templateFile);

    public const uint GENERIC_WRITE = 0x40000000;
    public const uint GENERIC_READ  = 0x80000000;
like image 174
Dave Cluderay Avatar answered Aug 06 '26 14:08

Dave Cluderay