The following program throws an error on “Console.ReadKey()”.
How do I re-enable the console after disabling it?
using System;
using System.Threading;
using System.Runtime.InteropServices;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem((o) =>
{
Thread.Sleep(1000);
IntPtr stdin = GetStdHandle(StdHandle.Stdin);
CloseHandle(stdin);
});
Console.ReadLine();
Console.Write("ReadLine() successfully aborted by background thread.\n");
Console.Write("[any key to exit]");
Console.ReadKey(); // Throws an exception "Cannot read keys when either application does not have a console or when console input has been redirected from a file. Try Console.Read."
}
// P/Invoke:
private enum StdHandle { Stdin = -10, Stdout = -11, Stderr = -12 };
[DllImport("kernel32.dll")]
private static extern IntPtr GetStdHandle(StdHandle std);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hdl);
}
}
Extra for Experts
If you’re wondering, I need to be able to kill a background thread running ReadLine(), within C#. This appears to be the only way (thread.Abort won’t work because ReadLine() runs deep within the bowels of the operating system, in unmanaged code). There is a lot of talk on this topic on StackOverflow, nobody has really discovered (or posted) a satisfactory method of aborting Console.ReadLine() yet. I think this code is on the right track – if only we can re-enable the console after disabling it.
Don’t know if it helps, but when I’ve needed to be able to write to the console in a win form app, I’ve used this class:
Call AllocConsole to create a console and then you can write to (and read from) it. Then call FreeConsole when you’re done.