如何确定Console.Out是否已重定向到文件?

如果我的程序正在打印到控制台,我会根据Console.WindowWidth通过插入换行符以某种方式执行自动换行 – 这很有效。

但是,如果程序的输出被重定向到文件或其他程序,我希望它跳过自动换行。 如何检测到这种情况?

Console.WindowWidth在两种情况下都返回相同的数字。

如果解决方案可以区分重定向的Console.Out与重定向的Console.Error,则可以获得奖励积分。

p /调用GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) ,或者调用像GetConsoleScreenBufferInfo这样无害的控制台函数来检查无效的句柄错误。 如果您想了解标准错误,请使用STD_ERROR_HANDLE 。 我相信你甚至可以比较GetStdHandle(STD_OUTPUT_HANDLE)GetStdHandle(STD_ERROR_HANDLE)返回的句柄来检测2>&1类的东西。

.NET 4.5添加了Console.IsOutputRedirectedConsole.IsErrorRedirected

虽然这有点阴暗,可能无法保证工作,你可以试试这个:

 bool isRedirected; try { isRedirected = Console.CursorVisible && false; } catch { isRedirected = true; } 

重定向控制台时,调用CursorVisible会引发exception。

你需要使用reflection – 有点肮脏,但以下将起作用:

 static bool IsConsoleRedirected() { var writer = Console.Out; if (writer == null || writer.GetType ().FullName != "System.IO.TextWriter+SyncTextWriter") return true; var fld = writer.GetType ().GetField ("_out", BindingFlags.Instance | BindingFlags.NonPublic); if (fld == null) return true; var streamWriter = fld.GetValue (writer) as StreamWriter; if (streamWriter == null) return true; return streamWriter.BaseStream.GetType ().FullName != "System.IO.__ConsoleStream"; } 

为什么输出包装在重定向文件中? 控制台执行的包装不是通过换行符。 换句话说,这个字符串:

你好,我叫Andrew Hare

会像这样包裹在一个瘦的控制台中:

你好,我的
e是安德鲁
野兔

但如果你要将输出重定向到一个文件,它将被写成如下:

你好,我叫Andrew Hare

因为输出中没有真正的换行符。

不要那样做! 只需传递一个额外的命令行参数,该参数指定要应用的格式。 使用您的应用程序的人员以及将使用您的代码的人员更容易理解,更简单,更清晰。