Хобрук: Ваш путь к мастерству в программировании

С# Console.In.ReadToEnd() зависает при вводе пользователем, если данные не передаются в программу

Я пишу консольное приложение С#, которое принимает 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()

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

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

Есть идеи?


  • Если вы переформатируете свой вопрос, чтобы он не выглядел стеной текста, я думаю, вы заставите больше людей его прочитать. 12.12.2010
  • Я согласен с Марком, это настоящая боль читать... 12.12.2010
  • Сейчас переформатировал. Я надеюсь, что это менее сложно читать. 12.12.2010

Ответы:


1

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

11.12.2010
  • Я уже не проверяю Console.In, если они предоставили достаточно параметров. Нет ли способа определить, были ли данные переданы или нет, и немедленно выйти без ввода пользователем CTRL + Z? 12.12.2010
  • Нет, вам нужно, чтобы пользователь действовал через новую строку (используя ReadLine()) или CTRL+Z (используя ReadToEnd()). 12.12.2010

  • 2

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

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

    Я скопировал это из https://stackoverflow.com/a/3453272/17034.

    28.04.2016
  • Скопировано без указания авторства с сайта stackoverflow.com/a/3453272/17034. 23.12.2020
  • Спустя четыре года я не помню об этом. 04.01.2021
  • Новые материалы

    Я собираюсь научить вас Python шаг за шагом
    Привет, уважаемый энтузиаст Python! 👋 Готовы погрузиться в мир Python? Сегодня я приготовил для вас кое-что интересное, что сделает ваше путешествие более приятным, чем шарик мороженого в..

    Альтернатива шаблону исходящих сообщений для архитектуры микросервисов
    Познакомьтесь с двухэтапным сообщением В этой статье предлагается альтернативный шаблон для папки Исходящие : двухэтапное сообщение. Он основан не на очереди сообщений, а на..

    React on Rails
    Основное приложение Reverb - это всеми любимый монолит Rails. Он отлично обслуживает наш API и уровень просмотра трафика. По мере роста мы добавляли больше интерактивных элементов..

    Что такое гибкие методологии разработки программного обеспечения
    Что представляют собой гибкие методологии разработки программного обеспечения в 2023 году Agile-методологии разработки программного обеспечения заключаются в следующем: И. Введение A...

    Ториго  — революция в игре Го
    Наш следующий вызов против ИИ и для ИИ. Сможет ли он победить людей в обновленной игре Го? Обратите внимание, что в следующей статье AI означает искусственный интеллект, а Goban  —..

    Простое развертывание моделей с помощью Mlflow — Упаковка классификатора обзоров продуктов NLP от HuggingFace
    Как сохранить свои модели машинного обучения в формате с открытым исходным кодом с помощью MLFlow, чтобы позже получить возможность легкого развертывания. Сегодня модели упаковки имеют несколько..

    Математика и интуиция - Часть 1
    У каждой математической формулы есть доказательство. Часто эти доказательства слишком сложно понять, поскольку многие из них основаны на индукции, некоторые - на очень сложных наблюдениях, а..