我正在.NET 4中编写一个小型的交互式控制台应用程序。我想扩展它以便能够处理可选的重定向输入,例如:
echo hello | myapp.exe
麻烦当然是重定向输入窃取了“键盘流”,所以对Console.Read *()的任何调用都会返回null。
目前我所拥有的是:
// 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();
在UNIX上我可以打开一个到/ dev / tty的流来获取用户输入,但是如何在Windows上使这个工作?
谢谢!
[编辑]
基于克雷格回答的工作解决方案:
[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()));
}
我必须首先使用
从控制台中分离FreeConsole().
我可以选择使用
创建一个全新的控制台AllocConsole()
但这会创建另一个控制台窗口,我真的不想要。相反,我使用
附加到父控制台(现有的cmd.exe)AttachConsole(-1) // -1 = "Parent".
我只能推测.NET类控制台保存对前一个stdin流的引用,但只有在调用Console.SetIn()
之后Console.ReadLine()
才会恢复它的阻塞行为,等待用户输入
现在开始调查如果我使用我的应用程序的stdout重定向运行会发生什么:
echo hello | myapp.exe | somewhere ...