Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何确定Console.Out是否已重定向到文件?_C#_.net_Console - Fatal编程技术网

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

C# 如何确定Console.Out是否已重定向到文件?,c#,.net,console,C#,.net,Console,如果我的程序正在向控制台打印,我会根据console.WindowWidth插入换行符,以某种方式执行文字换行,这非常有效 但是,如果程序的输出被重定向到一个文件或另一个程序,我希望它跳过单词包装。在这种情况下,我如何检测 Console.WindowWidth在两种情况下返回相同的数字 如果解决方案能够区分重定向的Console.Out和重定向的Console.Error,则可获得奖励。为什么输出会包装在重定向文件中?控制台不采用换行方式进行包装。换句话说,此字符串: 你好,我叫安德鲁·黑尔

如果我的程序正在向控制台打印,我会根据console.WindowWidth插入换行符,以某种方式执行文字换行,这非常有效

但是,如果程序的输出被重定向到一个文件或另一个程序,我希望它跳过单词包装。在这种情况下,我如何检测

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


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

为什么输出会包装在重定向文件中?控制台不采用换行方式进行包装。换句话说,此字符串:

你好,我叫安德鲁·黑尔

将包装在一个瘦控制台中,如下所示:

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

但是,如果要将输出重定向到一个文件,则会这样写:

你好,我叫安德鲁·黑尔


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

p/invoke
GetFileType(GetStdHandle(STD\u output\u HANDLE))
,或者调用无害的控制台函数,如
getconsolescreeesbufferinfo
,检查无效的句柄错误。如果您想了解标准错误,请使用
STD\u error\u HANDLE
。我相信您甚至可以比较
GetStdHandle(STD\u OUTPUT\u HANDLE)
GetStdHandle(STD\u ERROR\u HANDLE)
返回的句柄来检测
2>&1

之类的内容,虽然这有点可疑,可能无法保证工作,但您可以尝试以下方法:

bool isRedirected;

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

当控制台被重定向时,调用CursorVisible会引发异常。

您需要使用反射-有点脏,但以下方法可以工作:

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";
}

不要那样做!只需传递一个附加的命令行参数,该参数指定要应用的格式。无论是使用你的应用程序的人还是使用你的代码的人,它都更简单、更清晰、更容易理解。

.NET4.5添加了
Console.IsOutputRedirected
Console.IsErrorRedirected

,确切地说,在一个瘦小的控制台中,它会被包装得很糟糕。这就是为什么我们要在输出到控制台之前包装自己(通过插入换行符和适当的缩进)。显然,这种方法还包装了重定向的输出,这正是我们试图避免的。您如何确保它在下一版本的.NET中也能正常工作?:)这就是为什么它有点脏。但这是唯一的选择。虽然它会做一些讨厌的事情,比如检查私有字段类型的名称。。。到目前为止,这仍然是最好的解决方案,其他解决方案也同样令人讨厌。我认为这是一种不错的技术。你肯定想让它被单元测试所覆盖,以确保它能跨框架版本变化工作。似乎对stdout有效。在仅重定向stderr、仅重定向stdout或同时重定向两者时,不区分情况。但对于某些用例来说仍然可以。当stdout被重定向时,它总是对我有效,我想这是唯一重要的,对吧?我不同意。程序应该尽可能地自己解决问题,而不是每次都问用户。也不同意。看看git的行为。像
git diff
这样的命令,除非通过管道或重定向到文件,否则只能通过较少的管道和某种着色器。是的,与基于反射的东西相比,它工作得非常完美,而且更加经得起未来的考验。谢谢可能重复的