【问题标题】:Reading cmd output real time实时读取cmd输出
【发布时间】:2014-09-17 09:39:22
【问题描述】:

我正在编写一个读取 python 脚本输出并在文本框中显示结果的程序。 由于脚本运行了很长时间,我希望能够每 1 秒(或每行写入后)看到输出。 现在我只能在进程结束时看到输出。 有人知道是什么问题吗?

我的代码的sn-p:

Process p = new Process();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.OutputDataReceived += new DataReceivedEventHandler (p_OutputDataReceived);
p.ErrorDataReceived += new DataReceivedEventHandler (p_ErrorDataReceived);
p.Exited += new EventHandler (p_Exited);
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "python.exe";
p.StartInfo.Arguments = "path " + commandline; 
p.Start(); 
StreamReader s = p.StandardOutput;
String output = s.ReadToEnd();
textBox3.Text = output;
p.WaitForExit();

【问题讨论】:

    标签: c# cmd


    【解决方案1】:

    我在自己的程序中采用以下方式:

    private static void startProgram(
        string commandLine )
    {
        var fileName = commandLine;
        var arguments = string.Empty;
        checkSplitFileName( ref fileName, ref arguments );
    
        var info = new ProcessStartInfo();
        info.FileName = fileName;
        info.Arguments = arguments;
    
        info.UseShellExecute = false;
        info.RedirectStandardOutput = true;
        info.RedirectStandardError = true;
    
        using ( var p = new Process() )
        {
            p.StartInfo = info;
            p.EnableRaisingEvents = true;
    
            p.OutputDataReceived += (s,o) => { 
                Console.WriteLine(o.Data);
            };
            p.Start();
    
            p.BeginOutputReadLine();
    
            p.WaitForExit();
        }
    }
    

    即我订阅了OutputDataReceived event 并致电BeginOutputReadLine method。另见this similar Stack Overflow question

    (我上面源码can be found here中的方法checkSplitFileName

    【讨论】:

      【解决方案2】:

      我从 C# 运行我的 Python 脚本时遇到了同样的问题。问题是 Python 缓冲了来自 stdout (print()) 的输出。

      你可以在这里做两件事之一。

      1. 在每个 print() 行之后将以下内容添加到您的 Python 脚本中以刷新输出。

      import sys
      print('Hello World!')
      sys.stdout.flush()
      

      2. 使用 -u 命令行参数运行 Python 编译器。这样你就不需要在每次打印后添加上面的刷新线了。

      ...
      p.StartInfo.FileName = "cmd.exe";
      p.StartInfo.Arguments = "python.exe -u path " + commandline; 
      ...
      

      【讨论】:

        【解决方案3】:

        默认情况下,Python 会缓冲其输出。 方法是将“-u”命令行参数传递给python。

        所以如果你想执行 say hello.py,你会这样做:

        python.exe -u hello.py

        这是适合我的 C# 代码。

        Process p = new Process();
        string op = "";
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.RedirectStandardError = true;
        p.StartInfo.CreateNoWindow = true;
        p.StartInfo.FileName = "c:\\python27\\python.exe";
        StreamReader outputStream = p.StandardOutput;
        StreamReader errorStream = p.StandardError;
        p.StartInfo.Arguments = @"-u hello.py";
        p.Start();
        string output = "";
        int offset = 0, readBytes = 0;
        char[] buffer = new char[512];
        do
        {
            output = outputStream.ReadLine();
            if (!string.IsNullOrEmpty(output))
            {
                txtOutput.AppendText(output);
                txtOutput.AppendText(Environment.NewLine);
                offset += readBytes;
                Application.DoEvents();
            }
            Thread.Sleep(3);
        } while (!p.HasExited);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-11
          • 2012-04-24
          • 1970-01-01
          相关资源
          最近更新 更多