AttachConsole (kernel32)
Last changed: LNK1123-84.26.94.125

.
Summary

C# Signature:

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool AttachConsole(uint dwProcessId);

VB Signature:

Declare Function AttachConsole Lib "kernel32.dll" (dwProcessId as UInt32) As Boolean

User-Defined Types:

ATTACH_PARENT_PROCESS, ERROR_ACCESS_DENIED

Notes:

When running an application that is GUI from a console window, you may want to echo something to that console window (such as command line options when the user specifies /? on the command line), but also don't want a console window popping up when you don't need it (such is the behavior of a windows C# 'Console Application'). In this case these work great, and are fully compatible thereafter with the .NET Console.xxx static functions.

Remarks and Important Stuff

Tips & Tricks:

To duplicate the 'Console Application' feel, you can use the below code and call AllocateConsole as soon as Main() is called. This will cause it to act just as a console application would normally. Except you have the freedom to not show the console window at all if you don't want to (ie, if you have a /SHOWGUI option, which you prefer never creates a console in the first place).

Sample Code:

Create a new C# Windows project and paste this code in your "Program.cs" file inside of the static class:

/// <summary>
/// Allocates a new console for the calling process.
/// </summary>
/// <returns>If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero.
/// To get extended error information, call Marshal.GetLastWin32Error.</returns>
[DllImport("kernel32",SetLastError=true)]
static extern bool AllocConsole();

/// <summary>
/// Detaches the calling process from its console
/// </summary>
/// <returns>If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero.
/// To get extended error information, call Marshal.GetLastWin32Error.</returns>
[DllImport("kernel32", SetLastError = true)]
static extern bool FreeConsole();

/// <summary>
/// Attaches the calling process to the console of the specified process.
/// </summary>
/// <param name="dwProcessId">[in] Identifier of the process, usually will be ATTACH_PARENT_PROCESS</param>
/// <returns>If the function succeeds, the return value is nonzero.
/// If the function fails, the return value is zero.
/// To get extended error information, call Marshal.GetLastWin32Error.</returns>
[DllImport("kernel32.dll", SetLastError=true)]
static extern bool AttachConsole(uint dwProcessId);

/// <summary>Identifies the console of the parent of the current process as the console to be attached.</summary>
const uint ATTACH_PARENT_PROCESS = 0xFFFFFFFF;

/// <summary>
/// calling process is already attached to a console
/// </summary>
const int ERROR_ACCESS_DENIED = 5;

/// <summary>
/// Allocate a console if application started from within windows GUI.
/// Detects the presence of an existing console associated with the application and
/// attaches itself to it if available.
/// </summary>
private static void AllocateConsole()
{
    //
    // the following should only be used in a non-console application type (C#)
    // (since a console is allocated/attached already when you define a console app)
    //
    if (!AttachConsole(ATTACH_PARENT_PROCESS) && Marshal.GetLastWin32Error() == ERROR_ACCESS_DENIED)
    {
        // A console was not allocated, so we need to make one.
        if (!AllocConsole())
        {
            MessageBox.Show("A console could not be allocated, sorry!");
            throw new Exception("Console Allocation Failed");
        }
        else
        {
            Console.WriteLine("Is Attached, press a key...");
            Console.ReadKey(true);
            // you now may use the Console.xxx functions from .NET framework
            // and they will work as normal
        }        
    }
}

Resources

Documentation
AttachConsole on MSDN, MSDN Library for VS.NET version v8.0 and PlatformSDK Library v10.0