如何检测Console.In(stdin)是否已被redirect?
我想编写一个具有不同行为的控制台应用程序,具体取决于input来自键盘还是来自文件。
可能吗? 在C#中最优雅的方式是什么?
你可以通过p /调用Windows FileType()API函数来find。 这是一个辅助类:
using System; using System.Runtime.InteropServices; public static class ConsoleEx { public static bool IsOutputRedirected { get { return FileType.Char != GetFileType(GetStdHandle(StdHandle.Stdout)); } } public static bool IsInputRedirected { get { return FileType.Char != GetFileType(GetStdHandle(StdHandle.Stdin)); } } public static bool IsErrorRedirected { get { return FileType.Char != GetFileType(GetStdHandle(StdHandle.Stderr)); } } // P/Invoke: private enum FileType { Unknown, Disk, Char, Pipe }; private enum StdHandle { Stdin = -10, Stdout = -11, Stderr = -12 }; [DllImport("kernel32.dll")] private static extern FileType GetFileType(IntPtr hdl); [DllImport("kernel32.dll")] private static extern IntPtr GetStdHandle(StdHandle std); }
用法:
bool inputRedirected = ConsoleEx.IsInputRedirected;
更新:这些方法被添加到.NET 4.5中的控制台类。 没有归属地,我可能会添加:(只需使用相应的方法,而不是这个辅助类。
https://msdn.microsoft.com/zh-cn/library/system.console.isoutputredirected.aspx https://msdn.microsoft.com/zh-cn/library/system.console.isinputredirected.aspx https:// msdn.microsoft.com/en-us/library/system.console.iserrorredirected.aspx
有趣的是,当一个pipe道打开时, System.Console.WindowHeight
和System.Console.WindowWidth
参数为零 ,我发现,由于在代码path中的几个ArgumentOutOfRangeException
,不关心控制台大小为零。
跨平台 :在Linux和Windows上的MS dotNET和Mono下的行为是一样的(我没有在Mac上试过)。
当STDIN或STDOUT被pipe道连接时,控制台的大小被设置为0.因此,在汉斯的实现的基础上,我的代码如下:
using System; public static class ConsoleEx { public static bool IsConsoleSizeZero { get { try { return (0 == (Console.WindowHeight + Console.WindowWidth)); } catch (Exception exc){ return true; } } } public static bool IsOutputRedirected { get { return IsConsoleSizeZero && !Console.KeyAvailable; } } public static bool IsInputRedirected { get { return IsConsoleSizeZero && Console.KeyAvailable; } } }
2016年更新 :增加了对IsConsoleSizeZero
代码的exception处理,以在更广泛的上下文中提高代码的可用性。
代码似乎仍然运行良好,至less从使用MonoDevelop / Xamarin Studio的经验来讲。
相关 :
-
MSDN: KeyAvailable
-
设置System.Console.WindowHeight在Mono下引发System.NotSupportedException 。
由于框架4.5存在属性Console.IsInputRedirected。 8-)
请参阅MSDN
https://msdn.microsoft.com/de-de/library/system.console.isinputredirected(v=vs.110).aspx