Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 确定控制台输出的结束_C#_Processstartinfo - Fatal编程技术网

C# 确定控制台输出的结束

C# 确定控制台输出的结束,c#,processstartinfo,C#,Processstartinfo,我在应用程序中接收控制台输出。我使用来自(公认的解决方案)的代码。 但我的OutputDataReceived中从未得到null。相反,我在输出的末尾有String.Empty。 使用String.NullOrEmpty而不只是比较null是否正确 static void Main(string[] args) { var command = @"wmic cpu get loadpercentage"; using (Proces

我在应用程序中接收控制台输出。我使用来自(公认的解决方案)的代码。 但我的OutputDataReceived中从未得到null。相反,我在输出的末尾有String.Empty。 使用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));

                    }

                }
            }
        }

更新:似乎无法进行多行输出。问题是为什么a.Data中没有空值

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

如果您希望通过模拟用户对
cmd.exe
的输入来运行运行各种其他进程的进程,则还必须模拟用户交互,以识别并响应正在执行的最终命令


想象自己处于一个真实用户的位置,思考他们如何处理这种情况。当他们在命令提示符窗口中执行命令时,该窗口是否在命令完成后关闭?没有。他们是否收到命令已完成的任何指示?某种程度上。首先,他们可能期望命令的输出符合某些特定的格式,这些格式通常包括命令已完成的一些指示符。其次,命令提示符窗口将显示一个新的提示符(即短语“命令提示符”中的“提示符”)

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

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


最后请注意,实际上您可以使用
进程
类来执行命令本身。这样做不需要
cmd.exe
。如果您自己将每个命令作为一个单独的进程执行,那么您最终会通过每个进程的stdout流的末尾收到进程终止的通知。

您应该总是在末尾得到一个
null
。您没有收到它的原因是您没有等待进程终止。您需要一个
进程.WaitForExit()
进程.Start()之后的某个地方(特别是在进程在调用
BeginOutputReadLine
之前退出的情况下)。@Cameron但我的进程(cmd.exe)永远不会退出。我想使用process.StandardInput.WriteLine键入多个命令并接收相应的输出您发布的代码在设置命令变量后不使用该命令变量,您的新进程可能不会执行任何操作如果该进程从未退出,则其标准输出将保持打开状态(默认情况下,无论如何),并且您将永远不会收到null。通过这些自动重置事件,您到底想实现什么?@Amplier No是问题的答案——正如Cameron指出的,CMD不会在您的代码中停止(看起来正是您想要实现某种远程CMD/telnet的内容)——因此它永远不会有“输出结束”。此外,没有任何类型的“命令执行结束”标记,因此您真的看不到“ping”或任何其他命令是否已完成或正在等待用户输入,或者是否打开了自己的子提示符,如“ftp”。“任何命令已完成的指示”,是的,这就是我所想的。谢谢