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.
Ejecución estándar (en consola, sin redirección)
Todo funciona como se espera en la consola.
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 ) oapplication.exe <input_file.txt
para la redirección de entrada(reemplace el
type
concat
en Linux )o
application.exe | grep pattern
application.exe | grep pattern
oapplication.exe >output_file.txt
para la redirección de salidao
type input_file.txt | application.exe | grep pattern
type input_file.txt | application.exe | grep pattern
oapplication.exe <input_file.txt >output_file.txt
para la redirección de entrada y salidaEjecució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
Ejecutando con consola oculta y entrada / salida / error redirigido
por ejemplo, desde una aplicación GUI (la consola no es visible en absoluto)
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