读取命令输出实时

时间:2014-09-17 09:39:23

标签: c# cmd

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

我的代码片段:

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

3 个答案:

答案 0 :(得分:4)

我在自己的程序中按照以下方式进行操作:

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

答案 1 :(得分: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; 
...

答案 2 :(得分:1)

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

因此,如果您要执行说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);