Nano Hash - криптовалюты, майнинг, программирование

Чтение/запись в программу командной строки в С#

Я пытаюсь поговорить с программой командной строки из С#. Это анализатор настроений. Это работает следующим образом:

CMD> java -jar analyser.jar

>Starting analyser...

{Здесь я хочу вставить элементы из моей программы на С#. Например:}

I love you!

{И программа отвечает - я хочу это прочитать}

Very Positive

Вот некоторый псевдокод:

Process.start("sentiment.exe");
Process.writeline("I love you");
string Response = Process.readline();

Какие методы C# предлагает для записи в стандартный ввод процесса и чтения из его стандартного вывода?

21.01.2014

  • А ваш вопрос....? 22.01.2014
  • Не понятно, что вы спрашиваете? 22.01.2014
  • Может быть, вы ищете | для связывания вывода одной программы с другой, например type my.txt | more... В общем, cmd /? решит много проблем, связанных с этим. 22.01.2014
  • Я добавил пример кода. 22.01.2014
  • Так работает ли код примера? Если нет, что происходит? Сообщения об ошибках? На самом деле ты ничего не просил. 22.01.2014
  • Мне совершенно ясно, к чему этот вопрос. 22.01.2014
  • Для чтения стандартного вывода проверьте: Process.BeginOutputReadLine msdn.microsoft.com/en-us/library/ Для записи на стандартный ввод: Process.StandardInput.WriteLine() 22.01.2014
  • @GeoffBattye вновь открыт. Не стесняйтесь писать это как ответ. :) 22.01.2014
  • возможный дубликат Как зафиксировать стандартный вывод/ошибку процесс? 22.01.2014
  • @CodeCaster это точная копия этого вопроса, но принятый ответ на этот вопрос настолько ужасен, что я хочу пометить его для удаления. 22.01.2014
  • @ Майкл, это не совсем то, что можно было бы считать хорошим ответом, но вы, конечно, всегда можете его улучшить. 22.01.2014

Ответы:


1

То, что вы пытаетесь сделать, это «перенаправить» стандартные каналы ввода и вывода для запускаемого вами процесса. Это позволит вам читать и писать в дочерний процесс через потоки C#.

Для этого сначала необходимо установить ссылку RedirectStandardInput и RedirectStandardOutput в классе ProcessStartInfo, который вы используете для запуска дочернего процесса:

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "otherprogram.exe";
p.Start();

Как только это будет сделано, p.StandardInput и p.StandardOutput станут StreamReader, присоединенными к входу и выходу дочернего процесса. В зависимости от точного ввода и вывода дочернего процесса вам может потребоваться быть осторожным, чтобы избежать взаимоблокировки (например, когда ваша программа ожидает вывода, в то время как другая программа ожидает ввода). Чтобы избежать этого, вы можете использовать BeginOutputReadLine для асинхронного получения вывода, если это необходимо.

22.01.2014
  • +1. Это хорошая отправная точка. Как указал Майкл Эденфилд в ответе, нужно заботиться о том, чтобы действительно читать вывод - искать похожие вопросы (т.е. упоминать RedirectStandardInput) для полных образцов/решений. 22.01.2014

  • 2

    Вот небольшая демонстрация, показывающая, как делать то, что вы просите.

    Это игрушечное приложение командной строки, которое просто читает из стандартного ввода и выводит обратно на стандартный вывод:

    class Echoer
    {
        static void Main(string[] args)
        {
            while (true)
            {
                var input = Console.ReadLine();
                Console.WriteLine("Echoing: " + input);
            }
        }
    }
    

    Это еще одно приложение командной строки, которое запускает вышеуказанное приложение, передает ему ввод и считывает его вывод:

    class Program
    {
        static void Main(string[] args)
        {
            ProcessStartInfo processStartInfo;
            processStartInfo = new ProcessStartInfo();
            processStartInfo.CreateNoWindow = true;
    
            // Redirect IO to allow us to read and write to it.
            processStartInfo.RedirectStandardOutput = true;
            processStartInfo.RedirectStandardInput = true;
            processStartInfo.UseShellExecute = false;
    
            processStartInfo.FileName = @"path\to\your\Echoer.exe";
    
            Process process = new Process();
            process.StartInfo = processStartInfo;
            process.Start();
            int counter = 0;
            while (counter < 10)
            {
                // Write to the process's standard input.
                process.StandardInput.WriteLine(counter.ToString());
    
                // Read from the process's standard output.
                var output = process.StandardOutput.ReadLine();
                Console.WriteLine("Hosted process said: " + output);
                counter++;
            }
    
            process.Kill();
    
            Console.WriteLine("Hit any key to exit.");
            Console.ReadKey();
        }
    }
    

    Если приложение, которое вы размещаете, не просто создает строку вывода в ответ на строку ввода, вы можете посмотреть на асинхронный захват вывода с помощью Process.BeginOutputReadLine (в связанной документации есть пример кода).

    22.01.2014

    3

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

    Ключевым моментом является то, что вам нужно ввести правильные аргументы для jar

    var processInfo = new ProcessStartInfo("java.exe", "-jar SentiStrengthCom.jar stdin sentidata data201109/ scale"){ ... }
    

    Ниже приведено рабочее решение:

        // Start the java server, probably in a background thread
        void bgw_DoWork(object sender, DoWorkEventArgs e)
        {
            string directory = ...; // the directory of jar
    
            var processInfo = new ProcessStartInfo("java.exe", "-jar SentiStrengthCom.jar stdin sentidata data201109/ scale")
            {
                // Initialize properties of "processInfo"
                CreateNoWindow = true,
                UseShellExecute = false, 
                WorkingDirectory = directory,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                RedirectStandardInput = true,
            };
    
            JavaSentiStrength = new Process();
            JavaSentiStrength.StartInfo = processInfo;
    
            JavaSentiStrength.Start();
    
            Console.WriteLine("SentiStrengthCom Java is running...");
    
            JavaSentiStrength.WaitForExit();
    
            int exitCode = 0;
            if (JavaSentiStrength != null) exitCode = JavaSentiStrength.ExitCode;
            Debug.WriteLine("Java SentiStrengthCom closed down! " + exitCode);
            JavaSentiStrength.Close();
            JavaSentiStrength = null;
    
        }
    
        // A button click
        private void btnRequest_Click(object sender, EventArgs e)
        {
            JavaSentiStrength.StandardInput.WriteLine("love you ");
            string s_out = JavaSentiStrength.StandardOutput.ReadLine();
            Debug.WriteLine("SentiStrengthCom output: " + s_out);
        }
    

    Выход

    Результат SentiStrengthCom: 3 -1 2

    Надеюсь, поможет!

    09.06.2014
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..