【问题标题】:Read from console process从控制台进程读取
【发布时间】:2009-06-11 15:20:09
【问题描述】:

我有一个进程,我可以启动和隐藏工作正常,但我想从控制台程序读取,当我运行时,而不是之后,我试图运行一个计时器,并且在滴答声时读取,但是我的程序只是崩溃,当它不崩溃时,我什么也得不到。

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

【问题讨论】:

  • 我也试过,直接运行进程而不是通过cmd

标签: c# .net windows


【解决方案1】:

问题是您在一个线程上运行并尝试使用另一个线程进行编写。当您使用 Timer 的滴答事件创建后台线程时,它不能有前端用户输入。

也许如果您解释了您要完成的工作的总体情况,我们可以更好地帮助您。

与此同时,您可能想要创建线程安全写入。这个article 将帮助您了解在不同线程上编写表单控件的问题和解决方案。

【讨论】:

  • 该程序是一个带有一些参数的进程,如果没有错误发生并且关闭是 selft,我要做的是运行该进程,阅读该进程完成了多长时间任务,而它不在之后执行任务,并将其写入我的程序中。 >>与此同时,您可能希望通过避免 Timer 滴答声和在同一进程中读取来实现单线程。你的意思是我应该尝试读取我调用该过程的函数?
【解决方案2】:

您可以显式创建 Process 实例(例如new Process)并使用OutputDataReceived 事件、方法BeginOutputReadLine() 以及完成后的CancelOutputRead()

一旦输出数据可用,将从不同的线程异步重复调用事件OutputDataReceived

【讨论】:

  • 我试过你的解决方案,作为问题的更新,现在它不会崩溃,但我也没有得到任何数据,我也不知道在哪里放置 CancelOutputRead() .
【解决方案3】:

我假设您遇到“线程交叉异常”,这可能是因为您在另一个线程上更新表单控件而不是 UI 线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-05
    • 2023-03-21
    • 1970-01-01
    • 2012-03-19
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多