通过 Process.Start(startInfo) 在另一个进程上出现奇怪的行为 - 继续
原始位置(通过 Process.Start(startInfo) 对另一个进程的奇怪行为)不允许我正确发布测试代码。我必须在这里开始一个新问题。
我们的C#(V3.5)需要调用C++可执行文件来处理原始数据文件并为我们生成结果文件。
它之前使用以下代码工作(没有 ReadToEnd() 或 ReadLine() 调用):
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
现在输入原始数据文件发生了变化(比以前更大)。我们对该可执行文件的调用将永远挂起。根据建议,我添加了 ReadToEnd() 或 ReadLine(),但它会挂起这些调用。所以我必须使用 startInfo.UseShellExecute = true;
或设置
startInfo.UseShellExecute = false;
// and with
startInfo.RedirectStandardError = false;
startInfo.RedirectStandardOutput = false;
不知道为什么?
以下是我测试的案例:
工作案例:
ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = true; startInfo.UseShellExecute = false; startInfo.RedirectStandardError = false; startInfo.RedirectStandardOutput = false; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = 路径; startInfo.Arguments = rawDataFileName; //startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1); 尝试 { 流程修正Process = Process.Start(startInfo); CorrectionProcess.WaitForExit(); }
工作案例:
ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = true; startInfo.UseShellExecute = true; startInfo.RedirectStandardError = false;//可以注释掉 startInfo.RedirectStandardOutput = false;//可以注释掉 startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = 路径; startInfo.Arguments = rawDataFileName; startInfo.WorkingDirectory = Util.GetParentDirectory(路径, 1); 尝试 { 流程更正Process = Process.Start(startInfo); CorrectionProcess.WaitForExit(); }
不工作情况(使用
ReadLine()
):ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = true; startInfo.UseShellExecute = false; startInfo.RedirectStandardError = true; startInfo.RedirectStandardOutput = true; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = 路径; startInfo.Arguments = rawDataFileName; //startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1); 尝试 { 流程更正Process = Process.Start(startInfo); while (! CorrectionProcess.HasExited) { Log.logItem(LogType.Performance, "读取错误消息@@@@", "DPTM:: CorrectData()", ""); 字符串 errorMsg = CorrectionProcess.StandardError.ReadLine(); // <-- 挂在这里 Log.logItem(LogType.Performance, "读取 errorMsg", "DPTM:: CorrectData()", "errorMsg=" + errorMsg); 字符串outputMsg = CorrectionProcess.StandardOutput.ReadLine(); Log.logItem(LogType.Performance, "读取outputMsg", "DPTM:: CorrectData()", "outputMsg=" + outputMsg); 线程睡眠(100); } }
不工作的情况(使用
ReadToEnd()
):ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = true; startInfo.UseShellExecute = false; startInfo.RedirectStandardError = true; startInfo.RedirectStandardOutput = true; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = 路径; startInfo.Arguments = rawDataFileName; //startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1); 尝试 { 流程更正Process = Process.Start(startInfo); while (! CorrectionProcess.HasExited) { Log.logItem(LogType.Performance, "读取错误消息@@@@", "DPTM:: CorrectData()", ""); 字符串 errorMsg = CorrectionProcess.StandardError.ReadToEnd(); // <-- 挂在这里! Log.logItem(LogType.Performance, "读取 errorMsg", "DPTM:: CorrectData()", "errorMsg=" + errorMsg); 字符串outputMsg = CorrectionProcess.StandardOutput.ReadToEnd(); Log.logItem(LogType.Performance, "读取outputMsg", "DPTM:: CorrectData()", "outputMsg=" + outputMsg); 线程.睡眠(100); } }
不工作情况:
ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = true; startInfo.UseShellExecute = false; startInfo.RedirectStandardError = true; startInfo.RedirectStandardOutput = true; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = 路径; startInfo.Arguments = rawDataFileName; //startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1); 尝试 { 流程更正Process = Process.Start(startInfo); Log.logItem(LogType.Performance, "读取错误消息@@@@", "DPTM:: CorrectData()", ""); 字符串 errorMsg = CorrectionProcess.StandardError.ReadToEnd(); // <-- 挂在这里! Log.logItem(LogType.Performance, "读取 errorMsg", "DPTM:: CorrectData()", "errorMsg=" + errorMsg); 字符串outputMsg = CorrectionProcess.StandardOutput.ReadToEnd(); Log.logItem(LogType.Performance, "读取outputMsg", "DPTM:: CorrectData()", "outputMsg=" + outputMsg); CorrectionProcess.WaitForExit(); }
The original location (strange behaviour on another process via Process.Start(startInfo)) doesn't allow me post test code properly. I have to start a new question here.
Our C#(V3.5) needs to call a C++ executable to process a raw data file and generate result files for us.
It worked before with the following code (without ReadToEnd() or ReadLine() call):
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
Now the input raw data file changed (bigger than before). Our call to that executable will hang forever. Based on advice, I added ReadToEnd() or ReadLine() but it will hang on those calls. So I have to either use startInfo.UseShellExecute = true;
or set
startInfo.UseShellExecute = false;
// and with
startInfo.RedirectStandardError = false;
startInfo.RedirectStandardOutput = false;
Don't know why?
Following are cases I tested:
working case:
ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = true; startInfo.UseShellExecute = false; startInfo.RedirectStandardError = false; startInfo.RedirectStandardOutput = false; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = path; startInfo.Arguments = rawDataFileName; //startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1); try { Process correctionProcess = Process.Start(startInfo); correctionProcess.WaitForExit(); }
working case:
ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = true; startInfo.UseShellExecute = true; startInfo.RedirectStandardError = false;//can be commented out startInfo.RedirectStandardOutput = false;//can be commented out startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = path; startInfo.Arguments = rawDataFileName; startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1); try { Process correctionProcess = Process.Start(startInfo); correctionProcess.WaitForExit(); }
NOT working case (using
ReadLine()
):ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = true; startInfo.UseShellExecute = false; startInfo.RedirectStandardError = true; startInfo.RedirectStandardOutput = true; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = path; startInfo.Arguments = rawDataFileName; //startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1); try { Process correctionProcess = Process.Start(startInfo); while (!correctionProcess.HasExited) { Log.logItem(LogType.Performance, "read errorMsg @@@@", "DPTM::correctData()", ""); string errorMsg = correctionProcess.StandardError.ReadLine(); // <-- Hangs here Log.logItem(LogType.Performance, "read errorMsg", "DPTM::correctData()", "errorMsg=" + errorMsg); string outputMsg = correctionProcess.StandardOutput.ReadLine(); Log.logItem(LogType.Performance, "read outputMsg", "DPTM::correctData()", "outputMsg=" + outputMsg); Thread.Sleep(100); } }
NOT working case (using
ReadToEnd()
):ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = true; startInfo.UseShellExecute = false; startInfo.RedirectStandardError = true; startInfo.RedirectStandardOutput = true; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = path; startInfo.Arguments = rawDataFileName; //startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1); try { Process correctionProcess = Process.Start(startInfo); while (!correctionProcess.HasExited) { Log.logItem(LogType.Performance, "read errorMsg @@@@", "DPTM::correctData()", ""); string errorMsg = correctionProcess.StandardError.ReadToEnd(); // <-- Hangs here! Log.logItem(LogType.Performance, "read errorMsg", "DPTM::correctData()", "errorMsg=" + errorMsg); string outputMsg = correctionProcess.StandardOutput.ReadToEnd(); Log.logItem(LogType.Performance, "read outputMsg", "DPTM::correctData()", "outputMsg=" + outputMsg); Thread.Sleep(100); } }
NOT working case:
ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = true; startInfo.UseShellExecute = false; startInfo.RedirectStandardError = true; startInfo.RedirectStandardOutput = true; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.FileName = path; startInfo.Arguments = rawDataFileName; //startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1); try { Process correctionProcess = Process.Start(startInfo); Log.logItem(LogType.Performance, "read errorMsg @@@@", "DPTM::correctData()", ""); string errorMsg = correctionProcess.StandardError.ReadToEnd(); // <-- Hangs here! Log.logItem(LogType.Performance, "read errorMsg", "DPTM::correctData()", "errorMsg=" + errorMsg); string outputMsg = correctionProcess.StandardOutput.ReadToEnd(); Log.logItem(LogType.Performance, "read outputMsg", "DPTM::correctData()", "outputMsg=" + outputMsg); correctionProcess.WaitForExit(); }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您在错误/输出缓冲区上陷入僵局。当您等待该进程完成时,您的第二个进程正在等待缓冲区释放。您需要异步读取输出/错误流来防止这种情况。
查看您的 MSDN 示例:哇,该示例确实令人困惑...如果他们只是将其限制为标准输出或标准错误,那么会更容易理解。
您需要首先设置数据处理程序
,然后调用
就像评论[令人困惑]建议不要尝试读取那里的输出。请改用处理程序。
you are deadlocked on the error/output buffer. Your second process is waiting for the buffer to free up while you are waiting for that process to finish. You need to asynchronously read output/error streams to prevent that.
Looking at your MSDN sample: wow that sample is really confusing... It would've been easier to follow if they just limited it to std out or std error.
You need to first set data handler
and then call
Just like comment [confusingly] advises do no try to read output there. Use handler instead.