2010-08-10 19 views

Respuesta

45

Lo puede averiguar p/invocando la función API de Windows FileType(). Aquí está 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: se han añadido estos métodos a la clase de consola en .NET 4.5. Sin atribución podría añadir :(basta con utilizar 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

+3

El código anterior se estableció para .NET 4.5 que ahora incluye las propiedades IsErrorRedirected, IsInputRedirected y IsOutputRedirected. –

+1

implementación interesante, lamentablemente no es aplicable para el desarrollo multiplataforma. –

+0

La función isatty() tiende a estar disponible en otras plataformas para una prueba similar. –

5

Curiosamente, cuando un tubo está abierto, los System.Console.WindowHeight y System.Console.WindowWidth Los parámetros son cero, que Me enteré debido a varios ArgumentOutOfRangeException en rutas de código que no importaban porque el tamaño de la consola era 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 canalizan bien STDIN o STDOUT, el tamaño de la consola se establece en 0. Por lo tanto sobre la base de la aplicació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: Agregado el manejo de excepciones al código IsConsoleSizeZero para mejorar la usabilidad del código en un contexto más amplio.

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

relacionada:

+0

Buena captura en 'Console.WindowHeight'! Sin embargo, no estoy tan seguro del uso de 'Console.KeyAvailable'. Por un lado, es perfectamente posible redirigir tanto la entrada como la salida, y su código no podría detectar eso. – jpbochi

+1

no funcionan para mí –

+0

Me estoy ejecutando en Debian Wheezy. El truco 0 == (Console.WindowHeight + Console.WindowWidth) funciona para mí. Por ejemplo, cuando mi aplicación se inicia a través de Monit, la suma es 0. Cuando se realiza manualmente desde el símbolo del sistema, es un número positivo. Cuando se ejecuta sin consola, KeyAvailable devuelve falso, pero si realmente llamo a ReadKey, produce cero. – BrandonLWhite

1

Lorenz respuesta es un buen comienzo, pero por desgracia sólo se puede utilizar una fuente de inspiración. Hay más modos para ejecutar una aplicación de consola.

  1. plazo estándar (en la consola, sin ningún cambio de dirección)

    trabajo Todo según lo esperado en la consola.

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

    por ejemplo

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

    (sustituir con typecat en Linux)

    o

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

    o

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

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

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

  4. Ejecutora con la consola oculta y de entrada/salida/error redirigido

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

  5. Ejecución con la consola oculta sin redirección de entrada/salida/error

Cada uno de éstos modo tiene su propio 'características' . El Console.WindowHeight y Console.WindowWidth funcionan en Windows para el 1er y 2do 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 utilizar para la detección de redirección en todos los casos. El IOException al leer Console.WindowHeight o Console.WindowWidth se lanza solamente cuando no hay salida a la consola (modo de ejemplo 3º) y sólo para de Windows.

Para detectar entrada redirección (en de Windows solamente) uso de 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 operativos de redirección y ... Trate de experimentar cómo detectarlos. Diferentes funciones de consola y funciones 'trabajo' (arrojar excepción, o cero valores de retorno) 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 utilice esta función para la entrada de la reorientación en Linux (detectar con OS/plataforma, por ejemplo, Mono para Windows), ya que puede causar más problemas cuando falsamente espera redirección y la la redirección no está activa.

Cuestiones relacionadas