2010-08-10 3 views

Antwort

45

Sie können herausfinden, indem Sie die Windows FileType() - API-Funktion aufrufen. Hier ist eine Hilfsklasse:

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

Verbrauch:

bool inputRedirected = ConsoleEx.IsInputRedirected; 

UPDATE: Diese Methoden wurden in der Console-Klasse hinzugefügt in .NET 4.5. Ohne Zurechnung wie ich hinzufügen möchte :(einfach die entsprechende Methode Klasse anstelle dieser Helfer verwenden.

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

Der obige Code wurde für .NET 4.5 implementiert, die jetzt die Eigenschaften IsErrorRedirected, IsInputRedirected und IsOutputRedirected enthält. –

+1

interessante Implementierung, leider ist es nicht für die plattformübergreifende Entwicklung anwendbar. –

+0

Die Funktion isatty() ist auf anderen Plattformen für einen ähnlichen Test verfügbar. –

5

Interessanterweise, wenn ein Rohr offen ist, die System.Console.WindowHeight und System.Console.WindowWidth Parameter sind Null, die Ich fand heraus, aufgrund mehrerer ArgumentOutOfRangeException 's in Code-Pfade, die nicht darauf geachtet, dass die Konsole Größe 0 war.

Kreuzplattform: Das Verhalten ist dasselbe unter MS dotNET und Mono auf Linux und Windows (Ich habe es nicht auf einem Mac versucht).

Wenn entweder STDIN oder STDOUT geleitet wird, wird die Konsole Größe auf 0 gesetzt auf Hans-Implementierung Aufbau, mein Code wie folgt:

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

-Update 2016: Added Ausnahmebehandlung zum IsConsoleSizeZero Code zur Verbesserung der Benutzerfreundlichkeit des Codes in einem breiteren Kontext.

Der Code scheint immer noch gut zu funktionieren, zumindest aus Erfahrung bei der Verwendung von MonoDevelop/Xamarin Studio.

Verwandte:

+0

Schöner Fang auf der 'Console.WindowHeight'! Ich bin mir nicht so sicher über die Verwendung von 'Console.KeyAvailable'. Zum einen ist es durchaus möglich, sowohl die Eingabe als auch die Ausgabe umzuleiten, und Ihr Code könnte dies nicht erkennen. – jpbochi

+1

funktionieren nicht für mich –

+0

Ich bin auf Debian Wheezy ausgeführt. Der Trick 0 == (Console.WindowHeight + Console.WindowWidth) funktioniert für mich. Zum Beispiel, wenn meine App über Monit gestartet wird, ist die Summe 0. Wenn manuell über die Eingabeaufforderung ist es eine positive Zahl. Beim Ausführen von Konsolenlos gibt KeyAvailable den Wert false zurück, aber wenn ich ReadKey aufruft, wird Null ausgegeben. – BrandonLWhite

1

Lorenz Antwort ist ein guter Anfang, aber leider nur eine Inspiration verwendet werden. Es gibt mehrere Modi zum Ausführen einer Konsolenanwendung.

  1. Standard-Lauf (in Konsole, ohne Umleitung)

    Aller Arbeit wie in der Konsole erwartet.

  2. mit Umleitung von der Konsole ausführen mit Standard-Ein- und/oder Standard-Ausgangsumleitungs

    z.B.

    type input_file.txt | application.exe(in Windows-) oder application.exe <input_file.txt zur Eingabeumleitung

    (ersetzen type mit cat in Linux)

    oder

    application.exe | grep pattern oder zur Ausgabe application.exe >output_file.txt Umleitungs

    oder

    type input_file.txt | application.exe | grep pattern oder application.exe <input_file.txt >output_file.txt für Eingangs- und Ausgangsumleitungs

  3. mit Umleitung von der Konsole mit der Standardausgabe Umleitungs und Fehlerausgang

    Executing z.B. application.exe >output_file.txt 2>error_file.txt

  4. mit versteckter Konsole ausführen und umgeleiteten Ein-/Ausgabe/error

    z.B. von einer GUI-Anwendung (Konsole ist überhaupt nicht sichtbar)

  5. mit versteckten Konsole Ausführen ohne Umleitung von Eingabe/Ausgabe/Fehler

Jeder dieser Modus seine eigene ‚Eigenschaften‘ hat . Die Console.WindowHeight und Console.WindowWidth arbeiten in Windows für den 1. und 2. Modus in der Standard-Weise. In Linux ist der Rückgabewert im 2. und 3. Modus Null. Unter Linux können Sie daher nicht nur die Weiterleitung von Eingaben erkennen.

Daher kann der Code aus der Lorenz-Antwort nicht für die Erkennung der Umleitung in allen Fällen verwendet werden. Die IOException wenn Console.WindowHeight oder Console.WindowWidth Lesen nur ausgelöst, wenn es ist keine Ausgabe(z dritten Modus) auf die Konsole und nur für Windows-.

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

Für alle anderen Umleitung und Betriebssysteme ... versuchen, zu experimentieren, wie sie erkennen:

Um Eingang Umleitung (in Windows- nur) Verwendung dieser Funktion zu erfassen. Verschiedene Konsoleneigenschaften und Funktionen "arbeiten" (Ausnahme auslösen, oder Nullwerte) für verschiedene Modi.

Getestet an Windows 7 .NET Framework 4 Client Profile und Mono JIT compiler version 4.2.1 (Debian 4.2.1.102+dfsg2-7ubuntu4).

WICHTIG:

Verwenden Sie diese Funktion für die Eingabe nicht in Linux Umleiten (Erkennung mit OS/Plattform, zB Mono für Windows), weil es mehr Probleme verursachen kann, wenn Sie fälschlicherweise Umleitung erwarten und die Umleitung ist nicht aktiv.