я пишу оболочку для CMD, но у меня проблемы с перенаправлением стандартного ввода - PullRequest
2 голосов
/ 15 августа 2010

ОК, вот что я делаю - я хочу написать приложение .net, которое перенаправляет стандартный вывод / вход в richtextbox. У меня это работает довольно хорошо, но как только я добавляю стандартный ввод в микс, мои команды чтения зависают. Вот соответствующий код из моей формы.

        Shell = new Process();
        Shell.StartInfo.FileName = "cmd";

        Shell.StartInfo.UseShellExecute = false;
        Shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        Shell.StartInfo.CreateNoWindow = true;

        //Shell.StartInfo.RedirectStandardInput = true;
        Shell.StartInfo.RedirectStandardOutput = true;
        Shell.StartInfo.RedirectStandardError = true;

        Shell.EnableRaisingEvents = true;
        Shell.OutputDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
        Shell.ErrorDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);

        Shell.Start();

        Timer consoleReader = new Timer();
        consoleReader.Interval = 200;
        consoleReader.Tick += new EventHandler(consoleReader_Tick);
        consoleReader.Start();
    }

    void consoleReader_Tick(object sender, EventArgs e)
    {
        textArea.AppendText(Shell.StandardOutput.ReadToEnd());
    }

Я также пытался сделать это с помощью методов асинхронного чтения, доступных в классе Process, но, опять же, как только я добавлю в смесь standardinputredirect = true, он зависнет после чтения, возможно, строки или около того.

Есть идеи, ребята?

[[EDIT]] Итак, вот пример программы. Я переместил этот код в консольное приложение, чтобы немного упростить ситуацию. Почему это сломано?

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace TestAsConsoleApp
{
    class Program
    {
        static Process Shell;
        static void Main(string[] args)
        {
            Shell = new Process();
            Shell.StartInfo.FileName = "cmd";

            Shell.StartInfo.UseShellExecute = false;
            Shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            Shell.StartInfo.CreateNoWindow = true;

            Shell.StartInfo.RedirectStandardInput = true;
            Shell.StartInfo.RedirectStandardOutput = true;
            Shell.StartInfo.RedirectStandardError = true;

            Shell.Start();

            Shell.EnableRaisingEvents = true;
            Shell.OutputDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
            Shell.BeginOutputReadLine();

            Shell.WaitForExit();
        }

        static void Shell_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null)
                Console.WriteLine(e.Data);
        }
    }
}

Ответы [ 2 ]

1 голос
/ 17 августа 2010

Пересмотренная программа не выглядит сломанной. Вы создаете запрос процесса всех потоков, которые будут перенаправлены. Вы запускаете асинхронное чтение вывода созданного процесса. Тогда просто подожди. В вашем случае созданный cmd.exe ничего не получает в своем входном потоке, поэтому он не будет выводить ничего. Может быть, попробуйте следующую программу. Запустите его и дайте несколько команд, таких как dir и т. Д., Он выдаст результат. Надеюсь, я не понял вашу проблему.

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;

    namespace TestAsConsoleApp
    {
        class Program
        {
            static Process Shell;
            static void Main(string[] args)
            {
                Shell = new Process();
                Shell.StartInfo.FileName = "cmd";

                Shell.StartInfo.UseShellExecute = false;
                Shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                Shell.StartInfo.CreateNoWindow = true;

                Shell.StartInfo.RedirectStandardInput = true;
                Shell.StartInfo.RedirectStandardOutput = true;
                Shell.StartInfo.RedirectStandardError = true;

                Shell.Start();
                //Shell.StandardInput.WriteLine("dir");

                Shell.EnableRaisingEvents = true;
                Shell.OutputDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
                Shell.BeginOutputReadLine();
//read input from your programs input and forward that to the created cmd 's input
                do
                {
                    string aLine = Console.ReadLine();
                    Shell.StandardInput.WriteLine(aLine);
                    if (aLine.ToLower() == "exit")
                        break;
                }while(true);

                Shell.WaitForExit();
            }

            static void Shell_OutputDataReceived(object sender, DataReceivedEventArgs e)
            {
                if (e.Data != null)
                    Console.WriteLine(e.Data);
            }
        }
    }
0 голосов
/ 15 августа 2010

Если вы читаете асинхронно, вам также не нужно читать синхронно - и ваш синхронный код нарушен, так как он блокирует до всех вывода, который вы не должны делать в потоке пользовательского интерфейса. Я бы просто пошел на асинхронный код на вашем месте.

Теперь, что вы пытаетесь сделать с консолью? Вы говорите, что стандартный ввод вызывает проблемы - что вы пытаетесь записать в него? Вы явно смываете?

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