it-swarm.com.de

C # Console empfängt Eingabe mit Pipe

Ich weiß, wie man Konsolenanwendungen mit Parametern programmiert, Beispiel: myProgram.exe param1 param2.

Meine Frage ist, wie ich mein Programm mit | arbeiten lassen kann, Beispiel: Echo "Word" | myProgram.exe?

36

Sie müssen Console.Read() und Console.ReadLine() so verwenden, als würden Sie Benutzereingaben lesen. Rohre ersetzen Benutzereingaben transparent. Beides kann nicht einfach verwendet werden (obwohl ich mir sicher bin, dass es durchaus möglich ist ...).

Bearbeiten:

Ein einfaches cat-Stilprogramm:

class Program
{
    static void Main(string[] args)
    {
        string s;
        while ((s = Console.ReadLine()) != null)
        {
            Console.WriteLine(s);
        }

    }
}

Und wenn ausgeführt, wie erwartet, die Ausgabe:

 C:\...\ConsoleApplication1\bin\Debug> echo "Foo bar baz" | ConsoleApplication1.exe 
 "Foo bar baz" 
 
 C:\...\ConsoleApplication1\bin\Debug> 
43

Das Folgende setzt die Anwendung nicht für die Eingabe aus und funktioniert, wenn Daten oder nicht weitergeleitet werden. Ein bisschen hack; und aufgrund des Fehlerfangs kann die Leistung nachlassen, wenn zahlreiche Pipe-Anrufe gemacht werden, aber ... einfach.

public static void Main(String[] args)
{

    String pipedText = "";
    bool isKeyAvailable;

    try
    {
        isKeyAvailable = System.Console.KeyAvailable;
    }
    catch (InvalidOperationException expected)
    {
        pipedText = System.Console.In.ReadToEnd();
    }

    //do something with pipedText or the args
}
15
CodeMiller

in .NET 4.5 ist es

if (Console.IsInputRedirected)
{
    using(stream s = Console.OpenStandardInput())
    {
        ...
11
gordy

So geht's:

static void Main(string[] args)
{
    Console.SetIn(new StreamReader(Console.OpenStandardInput(8192))); // This will allow input >256 chars
    while (Console.In.Peek() != -1)
    {
        string input = Console.In.ReadLine();
        Console.WriteLine("Data read was " + input);
    }
}

Dies ermöglicht zwei Verwendungsmethoden. Lesen von Standardeingabe :

C:\test>myProgram.exe
hello
Data read was hello

oder lesen von Pipe-Input :

C:\test>echo hello | myProgram.exe
Data read was hello
8
matt burns

Hier ist eine weitere alternative Lösung, die aus den anderen Lösungen zusammen mit einem Peek () zusammengestellt wurde.

Ohne den Peek () habe ich erfahren, dass die App nicht ohne Strg-C am Ende zurückkehrt, wenn "t.txt | prog.exe" ausgeführt wird, wobei t.txt eine mehrzeilige Datei ist. Aber nur "prog.exe" oder "echo hi | prog.exe" hat gut funktioniert.

dieser Code dient nur zur Verarbeitung von Pipe-Eingaben.

static int Main(string[] args)
{
    // if nothing is being piped in, then exit
    if (!IsPipedInput())
        return 0;

    while (Console.In.Peek() != -1)
    {
        string input = Console.In.ReadLine();
        Console.WriteLine(input);
    }

    return 0;
}

private static bool IsPipedInput()
{
    try
    {
        bool isKey = Console.KeyAvailable;
        return false;
    }
    catch
    {
        return true;
    }
}
3

Console.In ist ein Verweis auf einen TextReader, der um den Standardeingabestrom gewickelt ist. Wenn Sie große Datenmengen an Ihr Programm übergeben, ist es möglicherweise einfacher, auf diese Weise zu arbeiten.

2
Joel Mueller

es liegt ein Problem mit dem angegebenen Beispiel vor.

  while ((s = Console.ReadLine()) != null)

wartet auf eine Eingabe, wenn das Programm ohne geleitete Daten gestartet wurde. Daher muss der Benutzer manuell eine beliebige Taste drücken, um das Programm zu beenden.

1
Alex N

Dies funktioniert auch für

c:\MyApp.exe <input.txt

Ich musste einen StringBuilder verwenden, um die von Stdin erfassten Eingaben zu bearbeiten:

public static void Main()
{
    List<string> salesLines = new List<string>();
    Console.InputEncoding = Encoding.UTF8;
    using (StreamReader reader = new StreamReader(Console.OpenStandardInput(), Console.InputEncoding))
    {
        string stdin;
        do
        {
            StringBuilder stdinBuilder = new StringBuilder();
            stdin = reader.ReadLine();
            stdinBuilder.Append(stdin);
            var lineIn = stdin;
            if (stdinBuilder.ToString().Trim() != "")
            {
                salesLines.Add(stdinBuilder.ToString().Trim());
            }

        } while (stdin != null);

    }
}
0
Si Zi