[英]How can i display a process StandardOutput in textBox?
在form1构造函数中
cmd = " -i \"" + InputFile + "\" \"" + OutputFile + "\"";
backgroundWorker1.RunWorkerAsync();
然后
private void ConvertNow(string cmd)
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = exepath;
proc.StartInfo.Arguments = cmd;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
while (!proc.StandardOutput.EndOfStream)
{
string line = proc.StandardOutput.ReadLine();
textBox1.Text = line;
}
}
然后在工作事件中
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ConvertNow(cmd);
}
问题出在该行的ConvertNow方法中:
while (!proc.StandardOutput.EndOfStream)
我使用了一个断点,但到了一段时间,但是程序在此行之后挂起,因此永远不会进入字符串和textBox行。
我如何使它可以分散输出,可能在textBox中,或者在更好的控件中使richTextBox或其他东西出现?
这是我现在尝试的:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Diagnostics;
namespace ConvertVideo
{
public partial class Form1 : Form
{
string InputFile = @"e:\lightningsmov\MVI_7909.MOV";
string OutputFile = @"e:\lightningsmov\MVI_7909.mp4";
string cmd;
string exepath = @"E:\myffmpegstatic\ffmpeg-20151217-git-9d1fb9e-win64-static\bin\ffmpeg.exe";
FileInfo fi;
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.ProgressChanged += (sender, e) => textBox1.AppendText((string)e.UserState);
fi = new FileInfo(InputFile);
label2.Text = InputFile;
cmd = " -i \"" + InputFile + "\" \"" + OutputFile + "\"";
backgroundWorker1.RunWorkerAsync();
}
private void ConvertNow(string cmd)
{
try
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = exepath;
proc.StartInfo.Arguments = cmd;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardOutput = true;
// use this event
proc.OutputDataReceived += (sender, e) => backgroundWorker1.ReportProgress(0, e.Data); // use this for synchronization
proc.Start();
// and start asynchronous read
proc.BeginOutputReadLine();
// wait until it's finished in your background worker thread
proc.WaitForExit();
}
catch(Exception err)
{
string myerr = err.ToString();
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ConvertNow(cmd);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
textBox1.Text = e.ProgressPercentage.ToString();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
}
}
当我在行上使用断点时:
proc.OutputDataReceived += (sender, e) => backgroundWorker1.ReportProgress(0, e.Data);
并将鼠标放在proc上,我看到所有具有相同异常的属性:
BasePriority ='proc.BasePriority'引发了类型'System.InvalidOperationException'的异常
几乎所有类似的属性。 试图增加尝试并赶上来,但没有成功。
您的代码中存在一些问题。 最糟糕的情况:您尝试从不同于UI线程的线程中更新控件。
建议您将ConvertNow
方法更改为以下内容:
private void ConvertNow(string cmd)
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = exepath;
proc.StartInfo.Arguments = cmd;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardOutput = true;
// use this event
proc.OutputDataReceived += (sender, e) => backgroundWorker1.ReportProgress(0, e.Data); // use this for synchronization
proc.Start();
// and start asynchronous read
proc.BeginOutputReadLine();
// wait until it's finished in your background worker thread
proc.WaitForExit();
}
向您的后台工作人员添加一个ProgressChanged
事件(例如,在表单构造函数中):
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.ProgressChanged += (sender, e) => textBox1.AppendText((string)e.UserState);
因此,现在,只要您的进程将数据写入stdout,您都会在UI线程上调用一个事件,并将数据追加到文本框中。
更新 :如果您已经有一个用于backgroundWorker1.ProgressChanged
的处理程序,则无需添加其他处理程序,但可以插入行textBox1.AppendText((string)e.UserState);
直接在您的处理程序中。 但是,如果您是从其他部分调用backgroundWorker1.ReportProgress
,则应首先检查e.UserState
是否实际上是应添加到e.UserState
的字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.