Magical ConsoleManager class

by abutler 19. August 2011 14:51

Ever want to add a console window to a Forms app?  How about a cool console window for some output from your ASP.Net worker process?  Ok, it's not that cool, but here's a class that I wrote a while back that will do it.

 

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;

/// <summary>
/// Class for attaching a Console window to the current process
/// </summary>	
internal class ConsoleManager : IDisposable
{
	#region Win32 API functions
	[DllImport("kernel32.dll")]
	private static extern bool AllocConsole();
	[DllImport("kernel32.dll")]
	private static extern bool FreeConsole();
	[DllImport("kernel32.dll")]
	private static extern IntPtr GetConsoleWindow();
	#endregion

	#region singleton
	/// <summary>
	/// Nested class for accessing the singleton object
	/// </summary>
	class Nested
	{
		// Explicit static constructor to tell C# compiler
		// not to mark type as beforefieldinit (lazy loading)
		static Nested()
		{
		}
		internal static readonly ConsoleManager Instance = new ConsoleManager();
	}
	#endregion

	#region constructors
	private ConsoleManager()
	{
	}
	#endregion

	#region instance methods
	/// <summary>
	/// Returns true if a console window has been attached
	/// </summary>
	private bool HasConsole
	{
		get { return GetConsoleWindow() != IntPtr.Zero; }
	}

	/// <summary>
	/// Creates a new console instance if the process is not attached to a console already.
	/// </summary>
	/// <returns>true if a Console window was attached as a result of this call</returns>
	private bool ShowConsole()
	{
		bool consoleAllocated = false;
		if (!HasConsole)
		{
			AllocConsole();
			Console.Title = "Diagnostics Console";
			consoleAllocated = true;
		}
		return consoleAllocated;
	}

	/// <summary>
	/// If the process has a console attached to it, it will be detached and no longer visible. 
	/// Writing to the System.Console is still possible, but no output will be shown.
	/// </summary>
	/// <remarks>True if the Console window was freed / hidden</remarks>
	private bool HideConsole()
	{
		bool consoleHidden = false;
		if (HasConsole)
		{
			FreeConsole();
			consoleHidden = true;
		}
		return consoleHidden;
	}
	#endregion

	#region static methods
	/// <summary>
	/// Shows a Console window
	/// </summary>
	/// <returns>True if the Console window was shown as a result of this call</returns>
	public static bool Show()
	{
		return Nested.Instance.ShowConsole();
	}

	/// <summary>
	/// Hides the Console window
	/// </summary>
	/// <returns>True if the Console windows was hidden as a result of this call</returns>
	public static bool Hide()
	{
		return Nested.Instance.HideConsole();
	}

	/// <summary>
	/// Shows the console window if it is currently hidden, OR hides it when it is currently visible
	/// </summary>
	public static void Toggle()
	{
		if (Nested.Instance.HasConsole)
		{
			Nested.Instance.HideConsole();
		}
		else
		{
			Nested.Instance.ShowConsole();
		}
	}
	#endregion

	#region cleanup
	private bool _disposed;
	~ConsoleManager()
	{
		Dispose(false);
	}

	public void Dispose()
	{
		Dispose(true);
		GC.SuppressFinalize(this);
	}

	protected virtual void Dispose(bool disposing)
	{
		if (!_disposed)
		{
			if (disposing)
			{
				// Dispose managed resources here.
			}
			// Dispose unmanaged resources here.				
			HideConsole();
		}
		_disposed = true;
	}
	#endregion
}

About the authors

We like to rock ICS Bank 2

Month List