C # - Console.In.ReadToEnd () зависает при вводе пользователем, если данные не передаются в программу - PullRequest
5 голосов
/ 12 декабря 2010

Я пишу консольное приложение C #, которое принимает 2 параметра: myprogram.exe param1 param2

param2 является необязательным, и идея в том, что если его нет, получите данные по трубопроводу:

echo "hithere" | myprogram.exe param1

Я заставил эту часть работать, захватив Console.In.ReadToEnd(), когда передан только 1 параметр.

Проблема, с которой я сталкиваюсь, заключается в том, что когда передается только 1 параметр и данные не передаются, он просто сидит и слушает ввод пользователя, и единственный способ закрыть это Ctrl+C, чтобы завершить программу.

Вместо этого, есть ли способ вернуть ошибку и выйти из программы, если был задан только 1 параметр и данные не были переданы по каналу?


Чтобы проверить, есть ли что-нибудь ожидающее, я попытался использовать:

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

Это не сработало.

Я также попробовал «взлом», упомянутый внизу этого вопроса stackoverflow: C # Консоль получает входные данные с конвейером .

Есть идеи?

Ответы [ 2 ]

2 голосов
/ 12 декабря 2010

Вместо проверки консоли, проверьте командную строку. Если они передают достаточно аргументов, то предположим, что с консоли нечего получить. Если они не указывают достаточно параметров, то предположим, что URL будет поступать из консоли. Вам не нужно использовать ReadToEnd(), просто используйте ReadLine(), чтобы вы могли переходить строка за строкой. Если вы используете ReadToEnd(), вам нужно нажать CTRL + Z (или CTRL + D в Linux), чтобы указать конец входного потока.

0 голосов
/ 28 апреля 2016

Вы можете использовать следующую программу, чтобы проверить, перенаправлен ли стандарт в:

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