确定控制台输出的结束

本文关键字:结束 输出 控制台 | 更新日期: 2023-09-27 18:02:24

我在应用程序中接收控制台输出。我使用这里的代码(公认的解决方案)。但我从来没有得到null在我的OutputDataReceived。取而代之的是String。输出末尾的为空。使用String是正确的吗?NullOrEmpty而不是只比较null?

static void Main(string[] args)
        {
            var command = @"wmic cpu get loadpercentage";
            using (Process process = new Process())
            {
                process.StartInfo.FileName = "cmd.exe";
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.RedirectStandardInput = true;
                process.StartInfo.RedirectStandardError = true;
                StringBuilder output = new StringBuilder();
                StringBuilder error = new StringBuilder();
                using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
                using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
                {
                    process.OutputDataReceived += (sndr, a) =>
                    {
                        if (a.Data == null)
                        {
                            outputWaitHandle.Set();
                        }
                        else
                        {
                            output.AppendLine(a.Data);
                        }
                    };
                    process.ErrorDataReceived += (sndr, a) =>
                    {
                        if (a.Data == null)
                        {
                            errorWaitHandle.Set();
                        }
                        else
                        {
                            error.AppendLine(a.Data);
                        }
                    };
                    process.Start();
                    process.BeginOutputReadLine();    
                    outputWaitHandle.WaitOne();
                    string path = "Test.txt";
                    using (StreamWriter sw = File.Exists(path) ? File.AppendText(path) : File.CreateText(path))
                    {
                        sw.WriteLine(String.Format("{0}, {1}", DateTime.Now, output));
                    }
                }
            }
        }

Update:似乎它不能工作多行输出。问题是为什么a.Data

确定控制台输出的结束

中没有null

标准输出流只有在流程本身终止时才会终止。注意,这里的"进程"是指运行cmd.exe的进程。该进程可以启动其他进程,但它们有自己的标准输出流,虽然这些进程的标准输出将在它们自己终止时终止,但这些都不会影响父进程cmd.exe的标准输出。

如果您想通过模拟用户输入cmd.exe来运行一个运行各种其他进程的进程,那么您还必须模拟识别并响应正在执行的最终命令的用户交互。

想象你自己在一个真正的用户的位置,想想他们如何处理这种情况。当他们在命令提示窗口中执行命令时,该窗口是否在命令完成后关闭?不。他们是否收到命令已完成的任何指示?排序的。首先,他们大概期望命令的输出符合某种特定的格式,这种格式通常会包含一些指示符,表明命令已经完成。其次,命令提示窗口将显示一个新的提示符(即短语"command-prompt"中的"prompt")。

请注意,恶意命令可以找出当前提示符的样子并伪造它。但这是不寻常的,想必您对发出的命令有足够的控制来避免这种情况。因此,一种方法是在输出出现时简单地处理输出,并检测命令完成时出现的新提示符。

如果这看起来不够可靠,那么您将不得不单独处理每个命令,解释命令的输出,并仅从该输出中的内容识别该命令何时到达其输出的末尾。

最后请注意,实际上您可以使用Process类来执行命令本身。你不需要cmd.exe来做到这一点。如果您自己将每个命令作为一个单独的进程执行,那么将通过每个进程的标准输出的流结束处获得进程终止的通知。