通过Process.Start(startInfo)在另一个进程上的奇怪行为

时间:2010-12-15 15:09:56

标签: c# .net

我们的C#(V3.5)应用程序需要调用来自其他公司的另一个C ++可执行文件。我们需要将原始数据文件名传递给它,它将处理原始数据(大约7MB)文件并生成16个结果文件(每个文件大约124K)。

调用该可执行文件的代码是:

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = exePath;
startInfo.Arguments = rawDataFileName;
try
{
Process correctionProcess = Process.Start(startInfo);
correctionProcess.WaitForExit();
}
catch(nvalidOperationException ex)
{
....
}
catch(...)
...

工作正常。现在我们有了新的原始数据。用新的原始数据文件替换旧的原始数据后。该可执行流程永远不会回复给我们。它将永远挂起。如果我们杀死我们的C#应用​​程序,那些结果文件将在目标directoy中生成。看起来可执行文件确实创建了那些结果文件,但是有问题要写入磁盘并返回给我们,直到进程终止。

与旧的原始数据文件不一样。

当我们直接使用新的原始数据运行可执行文件时(我们的C#app调用没有),它可以正常工作。这意味着此可执行文件对新原始数据没有任何问题。

我的问题1:这种行为的可能原因是什么?

现在,我使用startInfo.UseShellExecute = true;更改了代码并添加了startInfo.WorkingDirectory= ...,并禁用了

//startInfo.RedirectStandardError = true;
//startInfo.RedirectStandardOutput = true;

然后它有效。

我的问题2:为什么使用Windows Shell解决这个问题?

我的问题3:为什么它在没有使用Shell之前有效?

我的问题4:何时应该使用Shell而何时应该使用?

感谢,

3 个答案:

答案 0 :(得分:1)

几种可能性:

  • 您正在重定向输出和错误但不读取它。当stdout或stderr缓冲区填满容量时,该进程将停止。
  • 程序可能正在显示错误消息并等待按键。你不是重定向输入也不是检查stderr,按键永远不会来。
  • 某些程序,xcopy.exe是一个非常好的例子,当你重定向stdout时需要重定向stdin。虽然xcopy.exe的故障模式是立即退出而没有任何诊断。

当您杀死C#程序时看到它已修复,这使得第一颗子弹成为最有可能的原因。

答案 1 :(得分:0)

我知道这是一个非常普遍的问题。我必须处理输出,必须异步处理。当输出超过一定数量的数据时,你就不能WaitForExit。

您需要添加

myStdErr= correctionProcess.StandardError.ReadToEnd();

只有一次通常有效,如果你想过度杀戮这个作品(“P”是我的过程)

while (!P.HasExited)
  stdErr+= P.StandardError.ReadToEnd();

答案 2 :(得分:0)

如果您不需要stdout / stderr,只需将Redirect *属性设置为false。