问题
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 ...
回答1:
The AttachConsole function should do the job, though I've only used it to regain output rather than input.
来源:https://stackoverflow.com/questions/21779818/receiving-user-input-after-reading-piped-input