C# - Console.In.ReadToEnd()挂起用户输入,如果没有数据通过管道进程编程

时间:2010-12-11 23:33:47

标签: c# command-line console pipe

我正在编写一个带有2个参数的C#控制台应用程序:myprogram.exe param1 param2

param2是可选的,如果它不存在,那就是获取管道数据:

echo "hithere" | myprogram.exe param1

当只传递了1个参数时,我通过捕获Console.In.ReadToEnd()来使这部分工作。

我面临的问题是,当只传递1个参数且没有数据传输时,它只是在那里听取用户输入,关闭的唯一方法是Ctrl+C来结束程序。 / p>

相反,如果只提供了1个参数并且没有管道数据,是否有办法返回错误并退出程序?


为了测试是否有任何等待,我尝试使用:

  • Console.OpenStandardInput().CanRead
  • Console.OpenStandardInput().Length
  • Console.In.Peek()

那不起作用。

我也试过了这个stackoverflow问题底部提到的'hack':C# Console receive input with pipe

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

检查命令行,而不是检查控制台。如果他们传入足够的参数,那么假设没有任何东西可以从控制台获取。如果他们没有指定足够的参数,那么假设URL将来自控制台。您不需要使用ReadToEnd(),只需使用ReadLine(),这样您就可以逐行使用。如果你使用ReadToEnd(),你必须按CTRL + Z(或linux中的CTRL + D)来表示输入流的结束。

答案 1 :(得分:0)

您可以通过以下程序检查是否重定向标准输入:

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

用法:

bool inputRedirected = ConsoleEx.IsInputRedirected;

然后检查命令行参数的数量:

if (args.Length < 1)
# No parameters were passed
if (args.Length < 2)
{
   if (!inputRedirected)
   {
      Console.Error.WriteLine("You must redirect from stdin");
      # exit/die/end here
   }
}