鉴于以下代码,我似乎无法获得有效的Process.ExitCode - 如果设置了TraceOutput,它始终为0。 TraceOutput启用Stdout / Stderr捕获。如果我将TraceOutput设置为false,则每次都会正确输出退出代码:
protected ScanResult ExecuteScan(ProcessStartInfo processInfo)
{
processInfo.CreateNoWindow = true;
processInfo.ErrorDialog = false;
processInfo.UseShellExecute = false;
if (TraceOutput)
{
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;
}
using (var process = new Process())
{
process.StartInfo = processInfo;
// setup events to capture output, if tracing
if (TraceOutput)
{
process.OutputDataReceived += OutputDataReceived;
process.ErrorDataReceived += ErrorDataReceived;
}
// actually start the process
Trace.TraceInformation("Running scan: {0} {1}", processInfo.FileName, processInfo.Arguments);
process.Start();
// actually capture output, if tracing
if (TraceOutput)
{
process.BeginOutputReadLine();
process.BeginErrorReadLine();
}
// wait for the timeout, if supplied
bool finished;
if (Timeout == System.Threading.Timeout.Infinite)
{
process.WaitForExit();
finished = process.HasExited;
}
else finished = process.WaitForExit(Timeout);
// handle timeout expiry, by logging and marking as unknown
if (!finished)
{
Trace.TraceWarning("Scan timed out after {0:#,0} milliseconds", Timeout);
try
{
if (TraceOutput)
{
process.CancelOutputRead();
process.CancelErrorRead();
}
if (!process.HasExited)
process.Kill();
}
catch (Exception ex)
{
Trace.TraceWarning("{0} thrown while cleaning up scan process - {0}",
ex.GetType().Name,
ex.Message);
}
return ScanResult.Unknown;
}
if (TraceOutput)
{
process.CancelOutputRead();
process.CancelErrorRead();
}
// flush all output and gather exit code
do
{
process.WaitForExit();
}
while (!process.HasExited);
// if we exit with a valid success code, this is a successful scan
var exitCode = process.ExitCode;
var hasSuccessCode = (Array.IndexOf(SuccessExitCodes, exitCode) != -1);
return hasSuccessCode
? ScanResult.Ok
: ScanResult.Failed;
}
}
private static void OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (!string.IsNullOrWhiteSpace(e.Data))
Trace.WriteLine(e.Data, " :: Scan Stdout");
}
private static void ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if (!string.IsNullOrWhiteSpace(e.Data))
Trace.WriteLine(e.Data, " :: Scan Stderr");
}
// later...
SuccessExitCodes = new[] { 0 };
TraceOutput = true // TraceOutput is a property defined elsewhere...
var result = ExecuteScan(new ProcessStartInfo("myApp.exe", "args"));
我认为我已经阅读了各种MSDN子句,关于必须在没有参数的情况下调用WaitForExit,如果遇到异步方法的竞争条件,但是在完成此操作后,它仍会返回0
。
我错过了什么......?