博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c# 调用cmd 输出 阻塞 解决
阅读量:7038 次
发布时间:2019-06-28

本文共 1888 字,大约阅读时间需要 6 分钟。

引用:

异步输出

折叠
C# 代码
  1. Process p = CreateProcess("cmd",dir);//假如此处为我们从工厂中实例化一个调用cmd命令的进程   
  2. p.Start();   
  3. //从这里执行一个批处理或控制台程序,也可以是一堆CMD下的命令,我们通常会用这些来做大量的文件拷贝等操作   
  4. p.StandardInput.WriteLine("\"" + filename + "\" " + args);//写入执行参数   
  5. p.StandardInput.WriteLine("exit");//输入退出   
  6. //从此处获取所有输出信息   
  7. string result = p.StandardOutput.ReadToEnd();   
  8. p.WaitForExit();   
  9. //退出  

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

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

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

 

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

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

折叠
C# 代码
  1.         /// <summary>   
  2.         /// 生成进程   
  3.         /// </summary>   
  4.         /// <param name="filename"></param>   
  5.         /// <returns></returns>   
  6.         public static Process CreateProcess(string filename, string dir)   
  7.         {   
  8.   
  9.             Process p = new Process();//进程   
  10.             p.StartInfo.FileName = filename;   
  11.             p.StartInfo.RedirectStandardOutput = true;   
  12.             p.StartInfo.UseShellExecute = false;   
  13.             p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;   
  14.             p.StartInfo.CreateNoWindow = true;   
  15.            //下面二句不可少,不然会出错   
  16.             p.StartInfo.RedirectStandardInput = true;               
  17.             p.StartInfo.RedirectStandardError = true;   
  18.             if (!string.IsNullOrEmpty(dir))   
  19.                 p.StartInfo.WorkingDirectory = dir;   
  20.   
  21.             return p;   
  22.   
  23.         }   

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

折叠
C# 代码
  1. Process p = CreateProcess(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System),"cmd.exe"), dir);   
  2.                 StringBuilder result = new StringBuilder();   
  3.   
  4. //这里就是我们用来异步读取输出的二个委托事件   
  5. //一个是正确的信息,另一个是错误的信息输出   
  6. p.ErrorDataReceived += new DataReceivedEventHandler(delegate(object sender, DataReceivedEventArgs e)   
  7.                 {   
  8.                     //也可以是你自义定的其它处理,比如用console.write打印出来等。ShowErrorInfo(e.Data);   
  9.                     result.AppendLine(e.Data);   //收集所有的出错信息                    
  10.                 });   
  11.                 p.OutputDataReceived += new DataReceivedEventHandler(delegate(object sender, DataReceivedEventArgs e)   
  12.                 {   
  13.                     ShowNormalInfo(e.Data);   
  14.                     result.AppendLine(e.Data);                      
  15.                 });   
  16. p.Start();   
  17.   
  18. //这二句别忘了,不然不会触发上面的事件   
  19. p.BeginErrorReadLine();   
  20. p.BeginOutputReadLine();   
  21.   
  22. //可以做你要的操作,执行批处理或其它控制台程序   
  23. //。。。。。。。。。。。   
  24.   
  25. //p.StandardInput.WriteLine(input);   
  26. ///   
  27.   
  28. p.StandardInput.WriteLine("exit");//最后打入退出命令   
  29.   
  30. p.WaitForExit();   
  31. p.Close();   
  32. p.Dispose();  

转载地址:http://itnal.baihongyu.com/

你可能感兴趣的文章
关于Spring Data redis几种对象序列化的比较
查看>>
windows下批处理设置U盘盘符为U【非PE】
查看>>
Windows系统补丁KB2962872导致InstallShield无法启动(解决方案已更新)
查看>>
#每天问自己个问题#0. 每天问自己个问题
查看>>
制作免费的数字签名证书
查看>>
nagios3.3 监控端安装记录
查看>>
linux下拆分文件split
查看>>
BoCloud博云获得CNCF Kubernetes服务提供商认证
查看>>
WebApp 页面自适应
查看>>
【转自中科蓝鲸】集群NAS与集群文件系统的区别
查看>>
tigase网络核心SockThread详解
查看>>
iotop 查看进程IO情况
查看>>
php获取网站域名 及 SERVER 相关变量
查看>>
如何搭建springboot + mybatis(一)
查看>>
sphinx学习(六)基本配置 common settings
查看>>
win7下安装hadoop2.2.0.涵盖64位
查看>>
【推荐】Keras教程:Python深度学习超级入门指南
查看>>
CentOS/RedHat/Debian/Ubuntu下添加开机启动项
查看>>
C3P0数据库连接池
查看>>
通过Java反射调用方法
查看>>