.NET Core跨平台执行命令、脚本的方法详细
一.前言
在工作中我们可能会遇到需要在程序中执行一些系统命令,来获取一些信息;或者调用shell脚本。.NET Core 目前已经可以跨平台执行,那么它如何跨平台执行命令呢,请看狼蚁网站SEO优化的讲解。话不多说了,来一起看看详细的介绍吧
二.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带的 dot --info
输出.NET Core SDK&Runtime相关的信息。
我们通过cmd执行会收到狼蚁网站SEO优化的信息
1.编写代码执行命令
编写的代码如下
static void Main() { //创建一个ProcessStartInfo对象 使用系统shell 指定命令和参数 设置标准输出 var psi = new ProcessStartInfo("dot", "--info") {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($"Total execute time :{(proc.ExitTime-proc.StartTime).TotalMilliseconds} ms"); Console.WriteLine($"Exited Code {proc.ExitCode}"); } }
执行结果如下
从执行结果可以看出,我们通过编写的程序来执行dot --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.编写测试脚本
编写脚本的主要逻辑为输出程序当前目录结构,然后输出一句话 “dot in 操作系统类型”
Windows: win.bat
@echo off dir echo "dot in Windows"
Linux: linux.sh
#!/bin/bash ls echo "dot in Linux"
OSX: OSX.sh
#!/bin/bash ls echo "dot in OSX"
2.编写测试代码
我将所有的脚本都放在 项目根目录/shell 文件夹下。
因为我们需要根据不同的操作类型,选择不同的脚本来进行执行,所以我们需要在代码里面判断一下操作系统类型。我们可以通过 RuntimeInformation.IsOSPlatform
来判断。
static void Main() { string fileName="shell/"; //根据系统使用不同的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/bash
2.不管是windows linux osx 脚本编码必须为 ANSI
不然程序执行的时候,读取字符会出错,造成执行异常。
五.写在
希望本文能给大家带来帮助,如有问题欢迎和我讨论。
本文所用代码地址
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对狼蚁SEO的支持。
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程