从命令提示符重定向StandardOutput和StandardError(使用Delegates或AutoResetEvent)

时间:2014-02-20 13:44:55

标签: c# processstartinfo autoresetevent

我使用以下代码在命令提示符下执行一些命令并获取standardout和standarderror。该应用程序在80%的时间内工作正常,但对于某些命令,当输出有点重时,该过程用于挂起。然后我读到了关于委托标准输出和标准差的问题,就像我现在正在使用的https://stackoverflow.com/a/1146030/971363一样;

            var localeId = GetSystemDefaultLCID();
            var cultureInfo = CultureInfo.GetCultureInfo(localeId);
            var codePage = cultureInfo.TextInfo.OEMCodePage;
            var encoding = Encoding.GetEncoding(codePage);

            // The /c tells cmd that we want it to execute the command that follows, and then exit.
            var processStartInfo = new ProcessStartInfo
                {
                    FileName = "cmd.exe",
                    Arguments = "/c " + cliCommand,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    StandardOutputEncoding = encoding,
                    StandardErrorEncoding = encoding,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    WindowStyle = ProcessWindowStyle.Hidden,
                };

            this.cliProcess = new Process { StartInfo = processStartInfo };
            this.cliProcess.ErrorDataReceived += this.ProcessErrorDataReceived;
            this.cliProcess.OutputDataReceived += this.ProcessOutputDataReceived;
            this.cliProcess.EnableRaisingEvents = true;

            this.cliProcess.Start();

            this.cliProcess.BeginErrorReadLine();
            this.cliProcess.BeginOutputReadLine();

            this.cliProcess.WaitForExit(5000);

            // Gets the value that the associated process specified when it terminated.
            this.processExitCode = this.cliProcess.ExitCode;
            this.StandardOutputString = this.tmpStandardOutputString.ToString();
            this.StandardErrorString = this.tmpStandardErrorString.ToString();
            this.IsProcessSuccessful = this.processExitCode == 0;

    private void ProcessErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (string.IsNullOrWhiteSpace(e.Data))
        {
            return;
        }

        this.tmpStandardErrorString.AppendLine(e.Data);
    }

    private void ProcessOutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (string.IsNullOrWhiteSpace(e.Data))
        {
            return;
        }

        this.tmpStandardOutputString.AppendLine(e.Data);
    }

这种方法在一个场景中在今天的测试运行期间(它在90%的时间内正常运行)回复了堆栈溢出异常。

我确实在https://stackoverflow.com/a/7608823/971363中尝试了这种方法,但即使这样也不会始终如一。这个给了我一个objectdisposedexception,就像https://stackoverflow.com/users/83418/jeffrey-knight所指出的那样。

有人可以帮助我对这些方法中的任何一种进行排序。我在调用序列或代码中做错了吗?

很抱歉将此问题作为单独的问题发布。我对@ jeffrey-knight的帖子没有必要的声誉。

提前致谢, 乔。

0 个答案:

没有答案