这是否可能?在C#中最优雅的方式是什么?
您可以通过p/调用Windows FileType() API函数来查找。这是一个帮助类:
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的Console类中添加了。没有署名,我可以补充一下 :( 直接使用相应的方法而不是使用这个帮助类。
https://msdn.microsoft.com/en-us/library/system.console.isoutputredirected.aspx https://msdn.microsoft.com/en-us/library/system.console.isinputredirected.aspx https://msdn.microsoft.com/en-us/library/system.console.iserrorredirected.aspx
System.Console.WindowHeight
和System.Console.WindowWidth
参数为零,我发现这是由于在代码路径中没有考虑控制台大小为零而导致的多个ArgumentOutOfRangeException
。
跨平台:在Linux和Windows上的MS dotNET和Mono下行为相同(我还没有在Mac上尝试过)。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
代码添加了异常处理,以提高在更广泛的环境中使用代码的易用性。
从我的经验来看,代码仍然很有效,至少在使用MonoDevelop / Xamarin Studio时如此。
相关内容:
Console.WindowHeight
部分,你发现得真好!但是关于使用 Console.KeyAvailable
我不是太确定。首先,完全有可能重定向输入和输出,而你的代码将无法检测到这一点。 - jpbochi标准运行(在控制台上,没有任何重定向)
在控制台中一切正常。
从控制台执行带有标准输入和/或标准输出重定向的命令
例如
type input_file.txt | application.exe
(在Windows中),或者使用application.exe <input_file.txt
进行输入重定向
(在Linux中将type
替换为cat
)
或者
application.exe | grep pattern
或者 application.exe >output_file.txt
进行输出重定向
或者
type input_file.txt | application.exe | grep pattern
或者application.exe <input_file.txt >output_file.txt
进行输入和输出重定向
从控制台执行带有标准输出和错误输出重定向的命令
例如:application.exe >output_file.txt 2>error_file.txt
从GUI应用程序中执行带有隐藏控制台和重定向输入/输出/错误的命令(控制台完全不可见)
从隐藏控制台执行没有重定向输入/输出/错误的命令
Console.WindowHeight
和Console.WindowWidth
在Windows中按标准方式工作。在Linux中,第2种和第3种模式的返回值为零。因此,在Linux中,您无法检测到仅输入重定向。Console.WindowHeight
或Console.WindowWidth
时的IOException
异常。private static bool IsInputRedirected()
{
try
{
if (Console.KeyAvailable)
{
return (false);
}
}
catch (InvalidOperationException)
{
return (true);
}
return (false);
}
对于其他重定向和操作系统,请尝试实验如何检测它们。不同的控制台属性和函数在不同模式下会 '起作用' (抛出异常或返回零值)。
在Windows 7 .NET Framework 4 Client Profile
和Mono JIT compiler version 4.2.1 (Debian 4.2.1.102+dfsg2-7ubuntu4)
上进行了测试。
重要提示:
不要在Linux中使用此功能进行输入重定向(检测正在运行的操作系统/平台,例如Windows上的Mono),因为当您错误地期望重定向但是重定向未生效时,可能会导致更多麻烦。