C# 如何在文本框中显示流程标准输出?
在form1构造函数中C# 如何在文本框中显示流程标准输出?,c#,.net,winforms,C#,.net,Winforms,在form1构造函数中 cmd = " -i \"" + InputFile + "\" \"" + OutputFile + "\""; backgroundWorker1.RunWorkerAsync(); 然后 然后在嫁妆活动中 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { ConvertNow(cmd); } 问题出在以下行中的
cmd = " -i \"" + InputFile + "\" \"" + OutputFile + "\"";
backgroundWorker1.RunWorkerAsync();
然后
然后在嫁妆活动中
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ConvertNow(cmd);
}
问题出在以下行中的ConvertNow方法中:
while (!proc.StandardOutput.EndOfStream)
proc.OutputDataReceived += (sender, e) => backgroundWorker1.ReportProgress(0, e.Data);
我使用了一个断点,它到达了while,但是程序在这一行之后挂起,它永远不会进入字符串和文本框行
我怎样才能使它在文本框中显示输出,或者在更好的控件中显示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)
{
}
}
}
当我在线路上使用断点时:
while (!proc.StandardOutput.EndOfStream)
proc.OutputDataReceived += (sender, e) => backgroundWorker1.ReportProgress(0, e.Data);
将鼠标放在proc上,我看到里面的所有属性都有相同的异常:
BasePriority='proc.BasePriority'引发了类型为'System.InvalidOperationException'的异常
几乎所有的属性都是这样的。
尝试添加try-and-catch-around,但没有达到目的。代码中存在一些问题。最糟糕的情况是:您试图从与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
事件添加到后台工作程序(例如,在表单构造函数中):
现在,每当进程写入stdout时,都会得到一个在UI线程上调用的事件,并将数据附加到文本框中
更新:如果您已经有了
backgroundWorker1.ProgressChanged
的处理程序,则无需添加其他处理程序,但可以插入行textBox1.AppendText((字符串)e.UserState)直接在处理程序中输入code>。但是,如果您从我的其他部分调用backgroundWorker1.ReportProgress
,您应该首先检查e.UserState
是否实际上是一个应添加到文本框中的字符串 我看不出错误,这对我来说很好。也许这是您为流程启动的二进制文件的问题?它是否向stdout输出了一些东西?也许它用的是stderr?(顺便说一句:让我们清理这些评论,这不应该是聊天)我现在测试了,我看到行:proc.OutputDataReceived+=(sender,e)=>backgroundWorker1.ReportProgress(0,e.Data);所有属性上的错误:StandardOutput='proc.StandardOutput'引发了一个类型为'System.InvalidOperationException'的异常procOk的所有属性上都出现了相同的异常错误。让我像现在一样在问题中再次添加代码。我将在backgroundworker中的designer中添加,我在那里删除了progresschanged事件,并且我只使用您的行通过构造函数注册到它,这样就不会有错误。