天天看点

c# 调用cmd 输出 阻塞 解决

异步输出

折叠C# 代码

Process p = CreateProcess("cmd",dir);//假如此处为我们从工厂中实例化一个调用cmd命令的进程   

p.Start();   

//从这里执行一个批处理或控制台程序,也可以是一堆CMD下的命令,我们通常会用这些来做大量的文件拷贝等操作   

p.StandardInput.WriteLine("\"" + filename + "\" " + args);//写入执行参数   

p.StandardInput.WriteLine("exit");//输入退出   

//从此处获取所有输出信息   

string result = p.StandardOutput.ReadToEnd();   

p.WaitForExit();   

//退出  

上面的做法本身没有什么问题,但有二个缺点。

1,如果执行的程序有大量的输出信息,会导致进程阻塞,程序至此不会再跑。

2,如果我要同步获取输出信息也不可能,只能等所有的执行完成才行。

下面我们来解决这个问题:

首先定义一个工厂用来生成进程:

        /// <summary>   

        /// 生成进程   

        /// </summary>   

        /// <param name="filename"></param>   

        /// <returns></returns>   

        public static Process CreateProcess(string filename, string dir)   

        {   

            Process p = new Process();//进程   

            p.StartInfo.FileName = filename;   

            p.StartInfo.RedirectStandardOutput = true;   

            p.StartInfo.UseShellExecute = false;   

            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;   

            p.StartInfo.CreateNoWindow = true;   

           //下面二句不可少,不然会出错   

            p.StartInfo.RedirectStandardInput = true;               

            p.StartInfo.RedirectStandardError = true;   

            if (!string.IsNullOrEmpty(dir))   

                p.StartInfo.WorkingDirectory = dir;   

            return p;   

        }   

然后我们调用它生成一个进程:

Process p = CreateProcess(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System),"cmd.exe"), dir);   

                StringBuilder result = new StringBuilder();   

//这里就是我们用来异步读取输出的二个委托事件   

//一个是正确的信息,另一个是错误的信息输出   

p.ErrorDataReceived += new DataReceivedEventHandler(delegate(object sender, DataReceivedEventArgs e)   

                {   

                    //也可以是你自义定的其它处理,比如用console.write打印出来等。ShowErrorInfo(e.Data);   

                    result.AppendLine(e.Data);   //收集所有的出错信息                    

                });   

                p.OutputDataReceived += new DataReceivedEventHandler(delegate(object sender, DataReceivedEventArgs e)   

                    ShowNormalInfo(e.Data);   

                    result.AppendLine(e.Data);                      

//这二句别忘了,不然不会触发上面的事件   

p.BeginErrorReadLine();   

p.BeginOutputReadLine();   

//可以做你要的操作,执行批处理或其它控制台程序   

//。。。。。。。。。。。   

//p.StandardInput.WriteLine(input);   

///////////////   

p.StandardInput.WriteLine("exit");//最后打入退出命令   

p.Close();   

p.Dispose();  

下一篇: web service2