Читать из консоли процесс - PullRequest
1 голос
/ 11 июня 2009

У меня есть процесс, я могу запустить и скрыть, работает нормально, но я хочу читать из консольной программы, когда я запускаю, а не после, я пытался запустить таймер, чтение anbd на галочке, но моя программа просто вылетает, а когда нет, я вообще ничего не получаю.

            startInfo= new ProcessStartInfo("cmd.exe");
            startInfo.Arguments ="/C uus.exe "+ arg.ToString();
            startInfo.RedirectStandardError = true;
            startInfo.RedirectStandardOutput = true;
            startInfo.UseShellExecute = false;
            startInfo.CreateNoWindow = true;
            this.timer1.Enabled=true;
            this.listBox1.Items.Clear();
            p= Process.Start(startInfo);
                            Application.DoEvents(); 

        void Timer1Tick(object sender, EventArgs e)
    {
        string str="";
        str=p.StandardOutput.ReadLine();
        if(str != null)
        {
            this.Text=str.ToString();
            this.listBox1.Items.Add(str);
        }
        Application.DoEvents();
    }

Так что мне сделать, чтобы решить эту проблему?


Обновление: Я попробовал Бендер предложение Теперь моя программа больше не падает, но и не получает никаких данных

            proc.StartInfo.UseShellExecute=false;
            proc.StartInfo.CreateNoWindow=true;
            proc.StartInfo.RedirectStandardOutput=true;
            proc.StartInfo.RedirectStandardError=true;
            proc.StartInfo.FileName="uus.exe";
            proc.StartInfo.Arguments=arg;
            proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(SortOutputHandler);
            proc.Start();
            proc.BeginOutputReadLine();

    void SortOutputHandler(object o,System.Diagnostics.DataReceivedEventArgs e)
    {
        string str="";
        string str2="";
        str=e.Data.ToString();
        if(str!=null && str!="")
        {
            this.listBox1.Items.Add(str.ToString());
            this.Text=str.ToString();
        }
        str2=proc.StandardOutput.ReadLine();
        if(str2!=null && str2!="")
        {
            this.lsw1.Items.Add(str2.ToString());
        }
    }

гм


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

private delegate void TextAdderDelegate(string str);

void TextAdder(string str)
{
   if(this.lsw1.InvokeRequired==true)
   {
      Invoke(new TextAdderDelegate(TextAdder),new object[] {str});
   }
   else
   {
      this.lsw1.Items.Add(str);
   }
}

void SortOutputHandler(object o,System.Diagnostics.DataReceivedEventArgs e)
{
   string str="";

   if(e!=null)
   {
      if(e.Data!=null)
      {
         str=e.Data.ToString();
      }
   }
   TextAdder(str);
}

Ответы [ 3 ]

1 голос
/ 11 июня 2009

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

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

Тем временем вы можете захотеть создать потокобезопасные записи. Эта статья поможет вам понять проблему и решение проблемы написания элементов управления в разных потоках.

0 голосов
/ 11 июня 2009

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

0 голосов
/ 11 июня 2009

Вы можете создать экземпляр Process явно (например, new Process) и использовать событие OutputDataReceived, метод BeginOutputReadLine() и, когда закончите, CancelOutputRead() для этого.

Событие OutputDataReceived будет неоднократно вызываться асинхронно из другого потока , как только будут доступны выходные данные.

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