45

我知道如何使用参数对控制台应用程序进行编程,例如:myProgram.exe param1 param2。

我的问题是,如何使我的程序与 | 一起使用,例如:echo "word" | 我的程序.exe?

4

8 回答 8

46

您需要使用Console.Read()and Console.ReadLine(),就好像您正在阅读用户输入一样。管道透明地替换用户输入。你不能轻易地使用两者(尽管我确信这很有可能......)。

编辑:

一个简单的cat样式程序:

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

    }
}

运行时,如预期的那样,输出:

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

C:\...\ConsoleApplication1\bin\Debug>
于 2008-10-14T00:16:50.100 回答
19

以下内容不会暂停应用程序的输入并在数据通过不通过管道传输时工作。有点小技巧;并且由于错误捕获,当进行大量管道调用时,性能可能会有所下降,但是......很容易。

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
}
于 2010-11-02T00:45:03.340 回答
14

在 .NET 4.5 中是

if (Console.IsInputRedirected)
{
    using(stream s = Console.OpenStandardInput())
    {
        ...
于 2015-03-14T10:09:03.723 回答
11

这是这样做的方法:

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

这允许两种使用方法。从标准输入读取:

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

或从管道输入中读取:

C:\test>echo hello | myProgram.exe
Data read was hello
于 2014-01-20T17:17:28.463 回答
4

这是从其他解决方案加上 peek() 组合而成的另一个替代解决方案。

如果没有 Peek(),我在执行“type t.txt | prog.exe”(其中 t.txt 是一个多行文件)时,如果没有 ctrl-c,应用程序将无法返回。但只是“prog.exe”或“echo hi | prog.exe”工作正常。

此代码仅用于处理管道输入。

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;
    }
}
于 2012-03-15T00:30:25.213 回答
3

这也适用于

c:\MyApp.exe < input.txt

我不得不使用 StringBuilder 来操作从 Stdin 捕获的输入:

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

    }
}
于 2017-10-26T22:25:17.123 回答
2

Console.In 是对围绕标准输入流的 TextReader 的引用。当将大量数据传输到您的程序时,使用这种方式可能会更容易。

于 2008-10-14T01:00:02.683 回答
1

提供的示例存在问题。

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

如果程序在没有管道数据的情况下启动,将等待输入。所以用户必须手动按任意键退出程序。

于 2010-01-28T00:52:13.753 回答