淘宝客网站主题,正规的丹阳网站建设,登封 网站建设,小程序推广50个方法一.前言我们可能会遇到需要在程序中执行一些系统命令#xff0c;来获取一些信息#xff1b;或者调用shell脚本。.NET Core 目前已经可以跨平台执行#xff0c;那么它如何跨平台执行命令呢#xff0c;请看下面的讲解。二.ProcessStartInfo、Process 类介绍我们主要用到的两个… 一.前言我们可能会遇到需要在程序中执行一些系统命令来获取一些信息或者调用shell脚本。.NET Core 目前已经可以跨平台执行那么它如何跨平台执行命令呢请看下面的讲解。二.ProcessStartInfo、Process 类介绍我们主要用到的两个类就是 ProcessStartInfo 和 Process 他们的用法和.NET Framework下是一样的。1. ProcessStartInfo 类ProcessStartInfo主要设置一些我们需要创建的进程的参数。比如需要启动的应用程序的文件名参数等等。1构造方法它有三个构造方法public ProcessStartInfo();public ProcessStartInfo(string fileName);public ProcessStartInfo(string fileName, string arguments);fileName用于启动进程的应用程序。arguments在进程启动时传递给应用程序的命令行参数。2主要属性CreateNoWindow指示是否在新窗口中启动进程。RedirectStandardError指示应用程序的错误输出是否写入到流中。RedirectStandardInput指示是否从应用程序读取应用程序的输入流。RedirectStandardOutput指示应用程序的文本输出是否写入流。StandardErrorEncoding错误输出内容编码。StandardOutputEncoding文本输出内容编码。UseShellExecute指示是否使用操作系统shell启动进程。如果启动进程时使用shell则为true; 如果应该直接从可执行文件创建进程则为false。 默认值是true。该类并没有定义自己的方法因为它主要设置一些创建进程需要的参数信息。2. Process 类该类的主要作用是提供对本地和远程进程的访问并使你能够启动和停止本地系统进程。1.主要属性ExitCode获取退出代码。0表示正常 非0表示非正常退出。ExitTime获取关联进程退出的时间。StartTime获取关联进程启动的时间。HasExited获取一个值指示相关进程是否已终止。MachineName获取运行关联进程的计算机的名称。SessionId获取关联进程的终端服务会话标识符。StandardError获取读取应用程序错误输出的流。StandardInput获取应用程序输入内容的流。StandardOutput获取用于读取应用程序文本输出的流。Threads获取关联进程中正在运行的线程集合。2.主要方法Start 启动进程BeginErrorReadLine异步开始读取应用错误输出。BeginOutputReadLine异步开始读取应用标准输出。CancelErrorRead取消读取错误输出。CancelOutputRead取消读取标准输出。Close释放与此组件关联的所有资源。CloseMainWindow通过向其主窗口发送关闭消息来关闭具有用户界面的进程。Kill立即停止关联的进程。Refresh放弃已经在进程中缓存的关联进程的任何信息。WaitForExit等待关联进程退出可以设置超时时间如不设置则一直等待。3事件一共有三个事件ErrorDataReceived接收到关联进程输出错误数据。OutputDataReceived接收到关联进程输出标准数据。Exited关联进程退出三.在Windows OSX Linux 下执行命令这里我选择.NET Core带的 dotnet --info输出.NET Core SDKRuntime相关的信息。我们通过cmd执行会收到下面的信息1.编写代码执行命令编写的代码如下static void Main(){ //创建一个ProcessStartInfo对象 使用系统shell 指定命令和参数 设置标准输出var psi new ProcessStartInfo(dotnet, --info) { RedirectStandardOutput true}; //启动var procProcess.Start(psi); if (proc null){Console.WriteLine(Can not exec.);} else{Console.WriteLine(-------------Start read standard output--------------); //开始读取using (var sr proc.StandardOutput){ while (!sr.EndOfStream){Console.WriteLine(sr.ReadLine());} if (!proc.HasExited){proc.Kill();}}Console.WriteLine(---------------Read end------------------);Console.WriteLine($Total execute time :{(proc.ExitTime-proc.StartTime).TotalMilliseconds} ms);Console.WriteLine($Exited Code {proc.ExitCode});}
}执行结果如下从执行结果可以看出我们通过编写的程序来执行dotnet --info命令获取的结果几乎一样只有第一行的提示我们通过cmd执行命令输出的是中文我们通过程序调用执行输出的是英文这个问题有兴趣的朋友可以研究一下。2.在Linux上执行使用的系统环境为CentOS 7.2.NET Core sdk版本为2.0.3。直接执行命令结果如下我将代码上传到git server然后在linux上clone然后执行结果如下可以看到我们获取执行输出是没有问题的但是获取进程开始执行出错了无法从进程检索该信息现在我们移除统计执行时间的代码这下我们执行就没有问题了。从这里我们可以得出结论由于平台的差异获取一些信息可能会出现异常所以我们实际一定要在多个平台上测试。3.在OSX上运行我在OSX上的.NET Core SDK版本为2.0.0 很久没更新了。直接执行命令从git Clone代码执行结果如下可以看出我们在OSX上执行是没有问题的。四.在Windows OSX Linux 下执行脚本1.编写测试脚本编写脚本的主要逻辑为输出程序当前目录结构然后输出一句话 “dotnet in 操作系统类型”Windows: win.batecho offdirecho dotnet in WindowsLinux: linux.sh#!/bin/bashlsecho dotnet in LinuxOSX: OSX.sh#!/bin/bashlsecho dotnet in OSX2.编写测试代码我将所有的脚本都放在 项目根目录/shell 文件夹下。因为我们需要根据不同的操作类型选择不同的脚本来进行执行所以我们需要在代码里面判断一下操作系统类型。我们可以通过 RuntimeInformation.IsOSPlatform来判断。static void Main(){ string fileNameshell/; //根据系统使用不同的shell文件if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)){fileName win.bat;} else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) {fileName linux.sh;} else{fileName OSX.sh;} //创建一个ProcessStartInfo对象 使用系统shell 指定命令和参数 设置标准输出var psi new ProcessStartInfo(fileName) { RedirectStandardOutput true }; //启动var proc Process.Start(psi); if (proc null){Console.WriteLine(Can not exec.);} else{Console.WriteLine(-------------Start read standard output--------------); //开始读取using (var sr proc.StandardOutput){ while (!sr.EndOfStream){Console.WriteLine(sr.ReadLine());} if (!proc.HasExited){proc.Kill();}}Console.WriteLine(---------------Read end------------------);Console.WriteLine($Exited Code {proc.ExitCode});}
}3.在Windows下运行在windows下运行是完全正常的。4.在OSX运行直接运行会报一个权限异常如下使用命令加入执行权限chmod x OSX.sh然后再次执行可以看到成功执行了脚本。5.在Linux上运行直接运行也是会有权限问题的同样使用命令加入执行权限chmod x linux.sh然后再次执行可以看到成功执行了我们的脚本。4.容易犯的错误看见上面的例子我都成功执行了其实我踩了几个坑花了我不少时间来解决。1.sh脚本一定要指定命令解析器也就是这句话放在sh脚本开头#!/bin/bash2.不管是windows linux osx 脚本编码必须为 ANSI不然程序执行的时候读取字符会出错造成执行异常。五.写在最后希望本文能给大家带来帮助如有问题欢迎和我讨论。本文所用代码地址https://github.com/stulzq/BlogDemos/tree/master/DotnetCmd原文地址: http://www.cnblogs.com/stulzq/p/9074965.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com