• c# 调用cmd 输出 阻塞 解决


    引用: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();  
  • 相关阅读:
    B01-java学习-阶段2-面向对象
    A11-java学习-二维数组-面向对象概念-类的编写-测试类的编写-创建对象-使用对象-递归
    09-java学习-数组-冒泡排序-选择排序-数组工具类编写-查找-扩容
    08-java学习-数组-增强for循环-数组与方法-main函数参数
    07-java学习-方法重载-idea集成开发工具学习-项目-模块-包
    执行SQL语句---SELECT
    执行SQL语句---INSERT/UPDATE/DELETE
    undefined reference to `mysql_init'解决办法
    ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
    网络编程(三)---数据报套接字
  • 原文地址:https://www.cnblogs.com/sode/p/2583941.html
Copyright © 2020-2023  润新知