提问者:小点点

确定命令是否已在C#中的CMD中执行完毕


首先,我要祝大家2021年新年快乐。

-:导言:-

现在让我们回到正题!我正在用C#创建一个带有TCP客户端-服务器配置的R.a.T(远程管理工具)。在我意识到需要检测一个命令是否已经在C#应用程序创建的command-prompt进程中完成执行之前,一切都进行得很好。请看下面的代码。

private static Process CMDProc = null;
private static StreamWriter ToCMDShell = null;

public static void StartCMD()
{
       ProcessStartInfo PSInfo = new ProcessStartInfo
       {
             FileName = "cmd.exe",
             CreateNoWindow = true,
             UseShellExecute = false,
             RedirectStandardInput = true,
             RedirectStandardOutput = true,
             RedirectStandardError = true
       };

       CMDProc = new Process { StartInfo = PSInfo };
       CMDProc.Start();
       ToCMDShell = CMDProc.StandardInput;
       ToCMDShell.AutoFlush = true;
       CMDProc.BeginOutputReadLine();
       CMDProc.BeginErrorReadLine();
       CMDProc.OutputDataReceived += (s, e) => { /*Do something with e.Data*/ };
       CMDProc.ErrorDataReceived += (s, e) => { /*Do something with e.Data*/ };
       ToCMDShell.WriteLineAsync("ping 8.8.8.8"); //Execute a long running command in cmd terminal.
}

-:我想实现的目标:-

正如您可能猜到的那样,ping命令完成所需的时间取决于internet连接的速度,现在我想要的是,当一个长时间运行的命令(如“ping”)在终端中完成执行时,运行一个名为的方法,该命令是使用C#代码调用的。

--我到现在为止所做的努力--

我试图从事件处理程序接收的输出流中读取,但没有成功,因为除了ping之外,其他一些长时间运行的命令根本没有将数据写入输出流,因此它不是一个可靠的解决方案。是的,我也试着在互联网上搜索我的解决方案,但是没有成功!这就是为什么我在这里寻求你的帮助。

--:结束语:-

事先感谢一个想帮我做这件事的人。请让我知道,如果你想得到进一步的澄清有关这方面的内容。我将热切地等待您的善意解决和帮助。如有语言或语法错误,敬请原谅。再次感谢你帮助我!


共1个答案

匿名用户

使用等待完成,使用获取最终状态代码。

如果您从流中获得一些指示进程被挂起或冻结或需要终止的数据,则调用

如果您从流中获得一些指示您应该执行其他操作的数据,则可以派生其他进程或向该进程发送额外的调用以执行进一步的处理。

下面的程序将ping命令输出正确地发送回我。也许您只需要wait命令或控制台读取行来给它时间。

using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace MyNamespace
{
    class Program
    {
        private static Process CMDProc = null;
        private static StreamWriter ToCMDShell = null;

        public static void Main()
        {
            StartCMD();
        }    

        public static void StartCMD()
        {
            ProcessStartInfo PSInfo = new ProcessStartInfo
            {
                FileName = "cmd.exe",
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardInput = true,
                RedirectStandardOutput = true,
                RedirectStandardError = true
            };

            CMDProc = new Process { StartInfo = PSInfo };
            CMDProc.Start();
            ToCMDShell = CMDProc.StandardInput;
            ToCMDShell.AutoFlush = true;
            CMDProc.BeginOutputReadLine();
            CMDProc.BeginErrorReadLine();
            CMDProc.OutputDataReceived += (s, e) =>
            {
                Console.WriteLine("PROC: {0}", e.Data);
                if (e.Data != null && e.Data.Contains("Average ="))
                {
                    // last line, you don't have to exit here, you could do something else instead...
                    ToCMDShell.WriteLine("exit");
                }
            };
            CMDProc.ErrorDataReceived += (s, e) => Console.WriteLine("PROC ERR: {0}", e.Data);
            ToCMDShell.WriteLine("ping 8.8.8.8"); //Execute a long running command in cmd terminal.
            CMDProc.WaitForExit();
            Console.WriteLine("Job done, press ENTER to quit");
            Console.ReadLine();
        }
    }
}