如果ProcessStartInfo.RedirectStandardOutput为true,则Process.ExitCode始终为0

时间:2016-12-20 19:31:14

标签: c#

鉴于以下代码,我似乎无法获得有效的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

我错过了什么......?

0 个答案:

没有答案