Как определить, была ли перенаправлена ​​Console.Out в файл?

Если моя программа печатает на консоли, я выполняю перенос слов определенным образом в соответствии с Console.WindowWidth, вставляя новые строки - и это работает отлично.

Однако, если вывод программы перенаправляется в файл или другую программу, мне бы хотелось, чтобы она пропускала перенос слов. Как я могу определить, когда это так?

Console.WindowWidth возвращает одинаковое число в обоих случаях.

Бонус, если решение может отличить перенаправленную консоль. От перенаправленного Console.Error.

Ответы

Ответ 1

p/invoke GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) или вызовите безобидную консольную функцию, например GetConsoleScreenBufferInfo, чтобы проверить недопустимую ошибку дескриптора. Если вы хотите узнать о стандартной ошибке, используйте STD_ERROR_HANDLE. Я считаю, что вы можете даже сравнивать дескрипторы, возвращенные GetStdHandle(STD_OUTPUT_HANDLE) и GetStdHandle(STD_ERROR_HANDLE), чтобы обнаружить такие вещи, как 2>&1.

Ответ 2

.NET 4.5 добавляет Console.IsOutputRedirected и Console.IsErrorRedirected.

Ответ 3

Пока это немного теневое и, вероятно, не гарантируется работа, вы можете попробовать следующее:

bool isRedirected;

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

Вызов CursorVisible выдает исключение при перенаправлении консоли.

Ответ 4

Вам нужно использовать отражение - немного грубым, но следующее будет работать:

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

Ответ 5

Почему ouput wrap в перенаправленном файле? Обертка, которую делает консоль, не происходит при разрыве строк. Другими словами, эта строка:

Привет, меня зовут Эндрю Харе

обернется в тощую консоль следующим образом:

привет, мой нам
э Эндрю
Hare

но если вы должны перенаправить вывод в файл, он будет выглядеть следующим образом:

Привет, меня зовут Эндрю Харе

так как на выходе нет истинных разрывов строк.

Ответ 6

Не делай этого! Просто передайте дополнительный параметр командной строки, который указывает форматирование, которое вы хотите применить. Это проще, чище и проще понять, как людьми, которые будут использовать ваше приложение, так и людьми, которые будут работать над вашим кодом.