C# 从Process.Start()获取所需输出时出现问题
我正在开发一个应用程序,它调用多个命令行应用程序对一些视频文件进行后期处理 现在,我正试图用我的有线电视卡调谐器识别视频录制中的商业中断。这运行得很好,但我在获取所需的屏幕输出时遇到了问题C# 从Process.Start()获取所需输出时出现问题,c#,command-line,C#,Command Line,我正在开发一个应用程序,它调用多个命令行应用程序对一些视频文件进行后期处理 现在,我正试图用我的有线电视卡调谐器识别视频录制中的商业中断。这运行得很好,但我在获取所需的屏幕输出时遇到了问题 String stdout = null; using (var process = new Process()) { var start = new ProcessStartInfo(comskip, cmdLine); start.WindowStyle = ProcessWindow
String stdout = null;
using (var process = new Process())
{
var start = new ProcessStartInfo(comskip, cmdLine);
start.WindowStyle = ProcessWindowStyle.Normal;
start.CreateNoWindow = true;
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
process.StartInfo = start;
process.Start();
process.WaitForExit();
stdout = process.StandardOutput.ReadToEnd();
}
我希望stdout
能够抓取屏幕上显示的内容,就像手动启动应用程序(下面的屏幕截图)时一样,这是应用程序正在执行的操作的连续提要,并且在输出中混合了给出%进度的行,我想用它来更新进度条
但运行上述代码只会让我:
使用的命令行是:
“C:\Users\Chris\Google Drive\Tools\ComSkip\ComSkip.exe”“C:\Users\Chris\Desktop\ComSkip Tuning Files\Modern Family.wtv”“--ini=C:\Users\Chris\Desktop\ComSkip Tuning Files\ComSkip\u ModernFamily.ini”
根据命令行将ini文件设置为C:\Users\Chris\Desktop\ComSkip Tuning Files\ComSkip\u ModernFamily.ini
使用C:\Users\Chris\Desktop\ComSkip Tuning Files\ComSkip\u ModernFamily.ini作为初始值
我还尝试重定向StandardError
流并抓取process.StandardError.ReadToEnd()代码>但如果使用这些选项运行,进程将挂起
我是否错过了捕获我所希望的内容的内容,或者此应用程序的输出流是否可能转到其他不可访问的地方?请参阅关于重定向标准输出的部分。在读取输出之前等待子进程结束可能会导致挂起
特别是,这个例子说不要做你已经做过的事情:
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
您应该使用事件OutputDataReceived
和可能的ErrorDataReceived
,并更新处理程序中的进度条。请参阅上的重定向标准输出。在读取输出之前等待子进程结束可能会导致挂起
特别是,这个例子说不要做你已经做过的事情:
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
您应该使用事件OutputDataReceived
和可能的ErrorDataReceived
,并更新处理程序中的进度条。您必须设置以下内容:
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.UseShellExecute = false;
process.OutputDataReceived += new DataReceivedEventHandler(ReadOutput);
process.ErrorDataReceived += new DataReceivedEventHandler(ErrorOutput);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
并在ReadOutput
和ErrorOutput
private static void ErrorOutput(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
stdout = "Error: " + e.Data;
}
}
private static void ReadOutput(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
stdout = e.Data;
}
}
您必须设置以下内容:
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.UseShellExecute = false;
process.OutputDataReceived += new DataReceivedEventHandler(ReadOutput);
process.ErrorDataReceived += new DataReceivedEventHandler(ErrorOutput);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
并在ReadOutput
和ErrorOutput
private static void ErrorOutput(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
stdout = "Error: " + e.Data;
}
}
private static void ReadOutput(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
stdout = e.Data;
}
}
感谢您提出的等待流程的建议。当我重定向StandardError
时,应用程序才会出现挂起的问题。当我只使用标准输出时,它不会挂起。如果我将StandardError.ReadToEnd()
调用移动到WaitForExit()
之前,我仍然会得到相同的行为。至于使用异步事件的建议,一旦我能够确定屏幕输出的方向,我计划将它们用于进度条。感谢您关于等待进程的建议。当我重定向StandardError
时,应用程序才会出现挂起的问题。当我只使用标准输出时,它不会挂起。如果我在WaitForExit()
之前移动StandardError.ReadToEnd()
调用,我仍然会得到相同的行为。至于使用异步事件的建议,我计划在确定屏幕输出的位置后,将它们用于进度条。我没有提到它,但是我从这一点开始,针对OutputDataReceived
,我切换到了同步方法,同时我试图找出哪个流包含我需要的数据。。。。但我返回并重试了此操作,还包括对ErrorDataReceived
的支持。。。我找到了我的数据。不知道为什么同步方法不起作用,但你确实让我重新审视了我的解决方案。Thanks@psubsee2003不客气:)。两周前我在我的项目中使用了这段代码,注意到有些程序有时会将正常消息显示为错误,将错误显示为正常消息,可能是来自linux的错误端口,它具有不同的返回代码…我没有提到它,但是我从这一点开始,针对OutputDataReceived
,我切换到了同步方法,同时我试图找出哪个流包含我需要的数据。。。。但我返回并重试了此操作,还包括对ErrorDataReceived
的支持。。。我找到了我的数据。不知道为什么同步方法不起作用,但你确实让我重新审视了我的解决方案。Thanks@psubsee2003不客气:)。两周前,我在我的项目中使用了这段代码,注意到有些程序有时会将正常消息显示为错误,将错误显示为正常消息,可能是来自linux的错误端口,它具有不同的返回代码…process.WaitForExit()
在进程完成之前不会返回,因此如果您想同步处理这一切,您需要执行while(!\u process.HastExited)\u process.StandardOutput.ReadLine()
一次读取一行。process.WaitForExit()
在该过程完成之前不会返回,因此如果您想同步处理这一切,您需要在(!\u process.HastExited)\u process.StandardOutput.ReadLine()时执行代码>一次读取一行。