c# 调用cmd 输出 阻塞 解决

简介: 引用:http://www.jiamaocode.com/Cts/1031.html 异步输出 折叠C# 代码 Process p = CreateProcess("cmd",dir);//假如此处为我们从工厂中实例化一个调用cmd命令的进程    p.

引用:http://www.jiamaocode.com/Cts/1031.html

异步输出

折叠 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();  
相关文章
|
关系型数据库 API C#
C#调用执行命令行窗口cmd,及需要交互执行的处理
C#执行外部程序用到的是Process进程类,打开一个进程,可以指定进程的启动信息StartInfo(启动的程序名、输入输出是否重定向、是否显示UI界面、一些必要参数等)...
3082 0
C#调用执行命令行窗口cmd,及需要交互执行的处理
C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较
原文:C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较 使用Task,await,async,异步执行事件(event),不阻塞UI线程和不跨线程执行UI更新   使用Task,await,async 的异步模式 去执行事件(event) 解决不阻塞UI线程和不夸跨线程执行UI更新报错的最佳实践,附加几种其他方式比较 由于是Winform代码和其他原因,本文章只做代码截图演示,不做界面UI展示,当然所有代码都会在截图展示。
4903 0
|
C#
[C#]使用CMD命令删除文件函数
[C#]使用CMD命令删除文件函数,System.Diagnostics.Process
3437 0
|
C#
C# 调用cmd命令
/***************************************************************** * C# 调用cmd命令 * 说明: * 本文记录一下C#怎么调用cmd命令。
666 0
|
C#
C#中隐式操作CMD命令行窗口
原文: C#中隐式操作CMD命令行窗口 MS的CMD命令行是一种重要的操作界面,一些在C#中不那么方便完成的功能,在CMD中几个简单的命令或许就可以轻松搞定,如果能在C#中能完成CMD窗口的功能,那一定可以使我们的程序简便不少。
905 0
|
数据库 C# vr&ar
c#调用cmd命令,将doc转换为 pdf
c#调用cmd命令,将doc转换为 pdf   using System; using System.Collections.Generic; using System.
992 0