tags:

views:

76

answers:

3

How can I open a console window from within a non-console .NET application (so I have a place for System.Console.Out and friends when debugging)?


In C++ this can be done using various Win32 APIs:

/*
   EnsureConsoleExists() will create a console
   window and attach stdout (and friends) to it.

   Can be useful when debugging.
*/

FILE* const CreateConsoleStream(const DWORD stdHandle, const char* const mode)
{
    const HANDLE outputHandle = ::GetStdHandle(stdHandle);
    assert(outputHandle != 0);
    const int outputFileDescriptor = _open_osfhandle(reinterpret_cast<intptr_t>(outputHandle), _O_TEXT);
    assert(outputFileDescriptor != -1);
    FILE* const outputStream = _fdopen(outputFileDescriptor, mode);
    assert(outputStream != 0);
    return outputStream;
}

void EnsureConsoleExists()
{
    const bool haveCreatedConsole = (::AllocConsole() != 0);
    if (haveCreatedConsole) {
        /*
            If we didn't manage to create the console then chances are
            that stdout is already going to a console window.
        */
        *stderr = *CreateConsoleStream(STD_ERROR_HANDLE, "w");
        *stdout = *CreateConsoleStream(STD_OUTPUT_HANDLE, "w");
        *stdin = *CreateConsoleStream(STD_INPUT_HANDLE, "r");
        std::ios::sync_with_stdio(false);

        const HANDLE consoleHandle = ::GetStdHandle(STD_OUTPUT_HANDLE);
        assert(consoleHandle != NULL && consoleHandle != INVALID_HANDLE_VALUE);

        CONSOLE_SCREEN_BUFFER_INFO info;
        BOOL result = ::GetConsoleScreenBufferInfo(consoleHandle, &info);
        assert(result != 0);

        COORD size;
        size.X = info.dwSize.X;
        size.Y = 30000;
        result = ::SetConsoleScreenBufferSize(consoleHandle, size);
        assert(result != 0);
    }
}
+1  A: 

If it's purely for debugging, use the Debug class and send everything to the Debug Output window in Visual Studio.

Austin Salonen
A: 

You can use AttachConsole as described here:

http://www.pinvoke.net/default.aspx/kernel32.attachconsole

But as Austin said, if you're debugging in the debugger I'd suggest using the Debug class instead.

ho1
This looked promising, but alas the console window it creates is not attached to `System.Console.Out`.
pauldoo
I don't know anything about how to link those I'm afriad. There's the `AllocConsole` method, but I assume that you'd have the same issue in that case.
ho1
+1  A: 

You'll want to P/Invoke AllocConsole(). Be sure to do so early, before using any of the Console methods. Find the declaration at pinvoke.net

A really quick way to get a console: Project + Properties, Application tab, Output type = Console Application.

For a more permanent way to provide diagnostic output, you really want to use the Trace class. It is very flexible, you can use the app.exe.config file to determine where the trace output goes. Review the MSDN Library docs for the TraceListener class.

Hans Passant