pauldoo
pauldoo

Reputation: 18645

Create a console from within a non-console .NET application

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);
    }
}

Upvotes: 1

Views: 1343

Answers (3)

Hans Passant
Hans Passant

Reputation: 942348

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.

Upvotes: 2

Hans Olsson
Hans Olsson

Reputation: 55059

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.

Upvotes: 1

Austin Salonen
Austin Salonen

Reputation: 50235

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

Upvotes: 2

Related Questions