Question

I am writing a small, interactive console application in .NET 4. I want to extend this to be able to handle optional redirected input as well, like:

echo hello | myapp.exe

Trouble is of course that the redirected input steals the "keyboard stream", so any calls to Console.Read*() returns null.

What I have at the moment is:

// Read piped input
try
{
    bool keyAvailable = Console.KeyAvailable;
}
catch
{
    string redirected = Console.In.ReadToEnd();
    // Need to do something here to "un-redirect" stdin back to keyboard
}

// Always returns null
String userInput = Console.ReadLine();

On UNIX I could open a stream to /dev/tty to get user input, but how can I make this work on Windows?

Thanks!

[EDIT]

Working solution based on Craig's answer:

[System.Runtime.InteropServices.DllImport("kernel32.dll")]
static extern bool AttachConsole(int dwProcessId);
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
static extern bool FreeConsole();

try
{
     bool keyAvailable = Console.KeyAvailable;
}
catch
{
    string redirectedInput = Console.In.ReadToEnd();
    bool freed = FreeConsole();
    bool attached = AttachConsole(-1);
    Console.SetIn(new StreamReader(Console.OpenStandardInput()));
}

I have to start by detaching from the console altogether using

FreeConsole().

I could opt to create an entirely new console using

AllocConsole()

but that would create another console window, which I don't really want. Instead I attach to the parent console (the existing cmd.exe) using

AttachConsole(-1) // -1 = "Parent".

I can only speculate that the .NET class Console holds a reference to the previous stdin stream, but only after the call to Console.SetIn() the Console.ReadLine() is back to it's blocking behavior, waiting for user input.

Now on to investigate what happens if I run with my application's stdout redirected:

echo hello | myapp.exe | somewhere ...
Was it helpful?

Solution

The AttachConsole function should do the job, though I've only used it to regain output rather than input.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top