zoukankan      html  css  js  c++  java
  • 使用C#执行命令行程序并异步输出

    在程序中常常会需要运行命令行程序并获取其运行状态或运行结果,此时则需要使用Process类,最近研究了许多,自感颇有心得,现在分享给大家。

    废话少说,上代码:

     1         /// <summary>
     2         /// 运行命令
     3         /// </summary>
     4         /// <param name="command">要运行的命令</param>
     5         /// <param name="timeout">运行命令的超时</param>
     6         /// <param name="standardOutputEncoding">异步输出的编码方式</param>
     7         /// <param name="standardErrorEncoding">异步错误的编码方式</param>
     8         /// <param name="outputHandler">异步输出的委托</param>
     9         /// <param name="errorHandler">异步错误的委托</param>
    10         /// <returns></returns>
    11         public int RunCommand(string command, int timeout, Encoding standardOutputEncoding, Encoding standardErrorEncoding, DataReceivedEventHandler outputHandler, DataReceivedEventHandler errorHandler)
    12         {
    13             int exitCode = -1;
    14             using (Process cmdProcess = new Process())
    15             {
    16                 //在Windows中使用cmd /c [command]的方式可以运行绝大多数的命令行程序
    17                 cmdProcess.StartInfo.FileName = "cmd.exe";
    18                 cmdProcess.StartInfo.Arguments = "/c " + command;
    19                 //若要使用异步输出则必须不使用操作系统外壳
    20                 cmdProcess.StartInfo.UseShellExecute = false;
    21                 //打开输出重定向
    22                 cmdProcess.StartInfo.RedirectStandardOutput = true;
    23                 //打开错误重定向
    24                 cmdProcess.StartInfo.RedirectStandardError = true;
    25                 //若要使用异步输出则必须不创建新窗口
    26                 cmdProcess.StartInfo.CreateNoWindow = true;
    27                 //以下两行指定了输出使用的编码方式,Process将使用指定的编码方式解码输出流。
    28                 //若删除以下两行则Process会使用默认ANSI编码页解码输出流
    29                 //指定异步输出使用的编码方式
    30                 cmdProcess.StartInfo.StandardOutputEncoding = standardOutputEncoding;
    31                 //指定异步错误使用的编码方式
    32                 cmdProcess.StartInfo.StandardErrorEncoding = standardErrorEncoding;
    33                 //将输出处理函数重定向到输出处理委托
    34                 cmdProcess.OutputDataReceived += outputHandler;
    35                 //将错误处理函数重定向到错误处理委托
    36                 cmdProcess.ErrorDataReceived += errorHandler;
    37                 //启动控制台进程
    38                 cmdProcess.Start();
    39                 //开始异步读取输出流
    40                 cmdProcess.BeginOutputReadLine();
    41                 //开始异步读取错误流
    42                 cmdProcess.BeginErrorReadLine();
    43                 //等待进程退出
    44                 //timeout为等待的毫秒数
    45                 //若timeout为负则会无限期等待
    46                 cmdProcess.WaitForExit(timeout);
    47                 //结束异步读取错误流
    48                 cmdProcess.CancelErrorRead();
    49                 //结束异步读取输出流
    50                 cmdProcess.CancelOutputRead();
    51                 //若进程正常退出则将退出码置为进程退出码,否则置为超时码
    52                 if (cmdProcess.HasExited)
    53                 {
    54                     exitCode = cmdProcess.ExitCode;
    55                 }
    56                 else
    57                 {
    58                     exitCode = -2;
    59                 }
    60                 //清理进程使用的资源
    61                 cmdProcess.Close();
    62             }
    63             return exitCode;
    64         }


    使用这种方法运行命令行程序时,为了方法的简洁性,没有对输入流做处理。若多次调用本方法则会为每次调用启动一个进程,进程之间没有相关性,若有童鞋需要在同一进程中执行多条命令,则可以参考一下方案:

    1. 为cmdProcess重定向输入
    2. 将需要执行的多条命令写成一个bat文件,然后执行bat文件
    3. 若运行的命令行程序支持的话可以使用<重定向输入

    您需要为outputHandler和errorHandler提供一个符合DataReceivedEventHandler的委托,此委托可以为null

    在调用时可以使用匿名委托以将所有输出添加到一个List中。

    参考连接:

    1. Process类:http://msdn.microsoft.com/zh-cn/library/vstudio/System.Diagnostics.Process.aspx
    2. OutputDataReceived 事件:http://msdn.microsoft.com/zh-cn/library/vstudio/system.diagnostics.process.outputdatareceived.aspx
    3. 重定向输入:http://msdn.microsoft.com/zh-cn/library/system.diagnostics.processstartinfo.redirectstandardinput(v=vs.85).aspx
    4. 标准输出的首选编码:http://msdn.microsoft.com/zh-cn/library/system.diagnostics.processstartinfo.standardoutputencoding(v=vs.85).aspx

     

  • 相关阅读:
    Grafana+Prometheus监控mysql性能
    性能测试监控平台Grafana的使用
    搭建grafana+telegraf+influxdb服务器性能监控平台
    cocos2d-x jsb 防止触摸事件传递
    web app 相关记录
    如何在Teamcenter中使用PMI?
    浅谈人机工程应用在数字化工艺中的作用
    关于奇葩说
    一些感想
    关于起名
  • 原文地址:https://www.cnblogs.com/mlzx1991/p/CSharp_Process_Output_Encoding.html
Copyright © 2011-2022 走看看