【发布时间】:2015-07-01 04:51:46
【问题描述】:
我在 C# 表单中运行 process,其启动信息类似于 Redirect console output to textbox in separate program 和 C# get process output while running,进程运行正常,但输出需要很长时间才能出现在 DataReceived event 中。
我希望在流程生成文本后立即查看文本;根据Process standard output cannot be captured?(第一条评论),我需要等到 2 到 4 kb 的缓冲区才能填充事件触发。
根据要求,这是代码:
void pcs_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
textBox1.BeginInvoke((Action)delegate { textBox1.AppendText(text + "\n"); });
}
private void LER_Go_Click(object sender, EventArgs e)
{
// variables LiDARExtRep contains the full path to an executable file
// that runs in DOS and produces verbose output.
// LER_Path.Text is the parameter passed to LiDARExtRep (only one arg for this example)
ProcessStartInfo pStartInfo = new ProcessStartInfo(LiDARExtRep, LER_Path.Text);
pStartInfo.UseShellExecute = false;
pStartInfo.ErrorDialog = false;
pStartInfo.RedirectStandardError = true;
pStartInfo.RedirectStandardInput = true;
pStartInfo.RedirectStandardOutput = true;
pStartInfo.CreateNoWindow = true;
System.Diagnostics.Process pcs = new System.Diagnostics.Process();
pcs.StartInfo = pStartInfo;
bool pStarted = pcs.Start();
pcs.OutputDataReceived += new DataReceivedEventHandler(pcs_OutputDataReceived);
pcs.BeginOutputReadLine();
pcs.WaitForExit();
}
我看不出它有什么特别之处,它与我引用的示例完全相同...构造函数中的简单"Dir","/b/s" 应该会产生相同的结果。
有没有办法将缓冲区减少到几个字节,或者有更好的方法来执行命令行工具并“实时”接收输出?
背景:我用 C++ 写了一些命令行程序,效果很好很棒,但是年轻一代似乎害怕 DOS,所以我正在创建一个表单(GUI)来收集参数这些工具似乎比尝试在 C++ 中的每个程序上放置 GUI 少了很多的工作。如果我无法获得实时响应,我将不得不UseShellExecute = true; 并显示命令窗口。
【问题讨论】:
-
也许你可以在 BackGroundWorker msdn.microsoft.com/en-us/library/… 中运行你的进程
-
这对@jmc 有什么帮助?是否有关于 BackgroundWorker 的反馈,它将从可执行文件中获取标准输出?我只看到一个百分比。
-
你能发布你的可重现代码来运行这个过程吗?然后有人可以找到线索。
-
@emoacht,我已经包含了代码。它(几乎)是 MSN/Stack Overflow 上帮助代码的直接副本(感谢各自的作者)。
-
setvbuf(stdout,NULL,_IONBF,0);在第一个printf命令之前应该会有所帮助。
标签: c# forms process buffer stdout