在程序中常常会需要运行命令行程序并获取其运行状态或运行结果,此时则需要使用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 }
使用这种方法运行命令行程序时,为了方法的简洁性,没有对输入流做处理。若多次调用本方法则会为每次调用启动一个进程,进程之间没有相关性,若有童鞋需要在同一进程中执行多条命令,则可以参考一下方案:
- 为cmdProcess重定向输入
- 将需要执行的多条命令写成一个bat文件,然后执行bat文件
- 若运行的命令行程序支持的话可以使用<重定向输入
您需要为outputHandler和errorHandler提供一个符合DataReceivedEventHandler的委托,此委托可以为null
在调用时可以使用匿名委托以将所有输出添加到一个List中。
参考连接:
- Process类:http://msdn.microsoft.com/zh-cn/library/vstudio/System.Diagnostics.Process.aspx
- OutputDataReceived 事件:http://msdn.microsoft.com/zh-cn/library/vstudio/system.diagnostics.process.outputdatareceived.aspx
- 重定向输入:http://msdn.microsoft.com/zh-cn/library/system.diagnostics.processstartinfo.redirectstandardinput(v=vs.85).aspx
- 标准输出的首选编码:http://msdn.microsoft.com/zh-cn/library/system.diagnostics.processstartinfo.standardoutputencoding(v=vs.85).aspx