c# console redirect stdin

c# - ¿Cómo detectar si Console.In(stdin) ha sido redirigido?



redirect (4)

Como Framework 4.5 existe la propiedad Console.IsInputRedirected. 8-)

Ver MSDN

https://msdn.microsoft.com/de-de/library/system.console.isinputredirected(v=vs.110).aspx

Quiero escribir una aplicación de consola que tenga un comportamiento diferente dependiendo de si la entrada proviene del teclado o, por ejemplo, de un archivo.

¿Es posible? ¿Cuál es la forma más elegante de hacerlo en C #?


Curiosamente, cuando una tubería está abierta, los parámetros System.Console.WindowHeight y System.Console.WindowWidth son cero , lo cual descubrí debido a varias ArgumentOutOfRangeException en rutas de código que no se preocupaban porque el tamaño de la consola fuera cero.

Crossplatform : el comportamiento es el mismo en MS dotNET y Mono en Linux y Windows (no lo he probado en una Mac).

Cuando se canaliza STDIN o STDOUT, el tamaño de la consola se establece en 0. Por lo tanto, basándose en la implementación de Hans, mi código es el siguiente:

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

Actualización 2016 : Manejo de excepciones agregado al Código IsConsoleSizeZero para mejorar la usabilidad del código en un contexto más amplio.

El código aún parece funcionar bien, al menos hablando de la experiencia durante el uso de MonoDevelop / Xamarin Studio.

Relacionado :


La respuesta de Lorenz es un buen comienzo, pero lamentablemente solo puede usarse como inspiración. Hay más modos para ejecutar una aplicación de consola.

  1. Ejecución estándar (en consola, sin redirección)

    Todo funciona como se espera en la consola.

  2. Ejecución con redirección desde la consola con entrada estándar y / o redirección de salida estándar

    p.ej

    type input_file.txt | application.exe type input_file.txt | application.exe (en Windows ) o application.exe <input_file.txt para la redirección de entrada

    (reemplace el type con cat en Linux )

    o

    application.exe | grep pattern application.exe | grep pattern o application.exe >output_file.txt para la redirección de salida

    o

    type input_file.txt | application.exe | grep pattern type input_file.txt | application.exe | grep pattern o application.exe <input_file.txt >output_file.txt para la redirección de entrada y salida

  3. Ejecución con redirección desde la consola con salida estándar y redirección de salida de error

    por ejemplo, application.exe >output_file.txt 2>error_file.txt

  4. Ejecutando con consola oculta y entrada / salida / error redirigido

    por ejemplo, desde una aplicación GUI (la consola no es visible en absoluto)

  5. Ejecutando con consola oculta sin redireccionamiento de entrada / salida / error

Cada uno de estos modos tiene sus propias ''características''. Console.WindowHeight y Console.WindowWidth funcionan en Windows para el primer y segundo modo de la manera estándar. En Linux, el valor de retorno en el segundo y tercer modo es cero . Por lo tanto, en Linux no puede detectar la redirección solo de entrada.

Por lo tanto, el código de la respuesta de Lorenz no se puede usar para la detección de redirección en todos los casos. La IOException al leer Console.WindowHeight o Console.WindowWidth se Console.WindowWidth solo cuando no hay salida a la consola (por ejemplo, el tercer modo) y solo para Windows .

Para detectar la redirección de entrada (solo en Windows ) use esta función:

private static bool IsInputRedirected() { try { if (Console.KeyAvailable) { return (false); } } catch (InvalidOperationException) { return (true); } return (false); }

Para todos los demás sistemas de redirección y operativos ... intente experimentar cómo detectarlos. Diferentes funciones de consola y funciones ''work'' (throw exception, o zero return values) para diferentes modos.

Probado en Windows 7 .NET Framework 4 Client Profile y Mono JIT compiler version 4.2.1 (Debian 4.2.1.102+dfsg2-7ubuntu4) .

IMPORTANTE:

No use esta función para redirigir entradas en Linux (detectar OS / plataforma en ejecución, p. Ej., Mono para Windows) , ya que puede causar más problemas cuando falsamente espera la redirección y la redirección no está activa.


Puede averiguar p / invocando la función API de Windows FileType (). Aquí hay una clase de ayuda:

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

Uso:

bool inputRedirected = ConsoleEx.IsInputRedirected;

ACTUALIZACIÓN: estos métodos se agregaron a la clase de la consola en .NET 4.5. Sin atribución, podría agregar :( Simplemente use el método correspondiente en lugar de esta clase de ayuda.

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