2009-04-13 18 views
15

Si mi programa está imprimiendo en la consola, realizo el ajuste de palabras de cierta manera de acuerdo con Console.WindowWidth insertando nuevas líneas, y esto funciona perfectamente.¿Cómo puedo determinar si Console.Out ha sido redirigido a un archivo?

Sin embargo, si la salida del programa se redirige a un archivo u otro programa, me gustaría omitir el ajuste de palabras. ¿Cómo puedo detectar cuando este es el caso?

Console.WindowWidth devuelve el mismo número en ambos casos.

Bonificación puntos si la solución puede distinguir la consola redirigida. Salga de la consola redirigida. Error.

+0

posible duplicado de [Comprobar si la salida se redirige] (http://stackoverflow.com/questions/1169591/check-if-output-is-redirected) –

Respuesta

11

p/invoke GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)), o llame a una función de consola inocuo como GetConsoleScreenBufferInfo para comprobar si hay un error de manejo no válido. Si quiere saber sobre el error estándar, use STD_ERROR_HANDLE. Creo que incluso puede comparar identificadores devueltos por GetStdHandle(STD_OUTPUT_HANDLE) y GetStdHandle(STD_ERROR_HANDLE) para detectar cosas como 2>&1.

+0

Sí, funciona perfectamente y es más resistente al futuro que las cosas basadas en la reflexión. ¡Gracias! –

0

¿Por qué la salida se ajusta en el archivo redirigido? La envoltura que hace la consola no es por medio de saltos de línea. En otras palabras, esta cadena:

hola mi nombre es Andrew Hare

envolvería en una consola flaco como esto:

hola mi nam
correo es Andrew
Hare

pero si tuviera que redirigir la salida a un archivo que se escribiría así:

hola mi nombre es Andrew Hare

ya que no hay verdaderos saltos de línea en la salida.

+0

Exactamente - en una consola flaca que estaría envuelto en un crappy camino.Por eso nos envolvemos (insertando nuevas líneas y sangría apropiada) antes de enviar a la consola. Obviamente, este enfoque también envuelve la salida redirigida, que es lo que estamos tratando de evitar. –

+0

Reformulado para aclarar esto. –

8

Mientras que esto es un poco turbio y probablemente no se garantiza que funcione, puede probar esto:

bool isRedirected; 

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

Calling CursorVisible una excepción cuando se redirige la consola.

+0

Parece que funciona para stdout. No ofrece ninguna distinción entre los casos en los que solo se redireccionan stderr, stdout o ambos. Sin embargo, está bien para algunos casos de uso. –

+0

Siempre funcionó para mí cuando se redirigió el stdout, que me imagino que es realmente el único que importaría, ¿no? –

2

Es necesario utilizar la reflexión - un poco sucio, pero el siguiente trabajo:

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

¿Y cómo se asegura de que funcione en la próxima versión de .NET también? :) – ibz

+0

¿Por qué votar abajo? Es la única solución sugerida hasta ahora que funcionará ... –

+0

Es por eso que es un poco complicado. Pero es la única opción. –

0

no hacen eso! Simplemente pase un parámetro de línea de comando adicional que especifique el formato que desea aplicar. Es más simple, más limpio y más fácil de entender, tanto por las personas que usarán su aplicación como por las personas que trabajarán en su código.

+2

No estoy de acuerdo. Los programas deben resolver las cosas por sí mismos en la mayor medida posible, y no preguntarle al usuario todo el tiempo. –

+0

No estoy de acuerdo también. Mira cómo se comporta git. Los comandos como 'git diff' canalizan menos y algún tipo de colorizador a menos que estén canalizados o redirigidos a un archivo. –

9

.NET 4.5 agrega Console.IsOutputRedirected y Console.IsErrorRedirected.

Cuestiones relacionadas