.NET Core跨平台执行命令、脚本的方法详细
一.前言
在工作中我们可能会遇到需要在程序中执行一些系统命令,来获取一些信息;或者调用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 SDK&Runtime相关的信息。
我们通过cmd执行会收到下面的信息:
1.编写代码执行命令
编写的代码如下:
static void Main() { //创建一个ProcessStartInfo对象 使用系统shell 指定命令和参数 设置标准输出 var psi = new ProcessStartInfo("dotnet", "--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}"); } }
执行结果如下:
从执行结果可以看出,我们通过编写的程序来执行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.bat
@echo off dir echo "dotnet in Windows"
Linux: linux.sh
#!/bin/bash ls echo "dotnet in Linux"
OSX: OSX.sh
#!/bin/bash ls echo "dotnet 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
不然程序执行的时候,读取字符会出错,造成执行异常。
五.写在最后
希望本文能给大家带来帮助,如有问题欢迎和我讨论。
本文所用代码地址:https://github.com/stulzq/BlogDemos/tree/master/DotnetCmd
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对猪先飞的支持。
相关文章
- 这篇文章主要为大家详细介绍了ASP.NET购物车的实现过程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
- 这篇文章主要介绍了.NET Core下使用Kafka的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
- 在开发过程中,使用Visual Studio的断点调试功能可以很方便帮我们调试发现程序存在的错误,同样Visual Studio也支持对SQL Server里面的存储过程进行调试,下面就让我们看看具体的调试方法。...2021-09-22
- 这篇文章主要介绍了Win10 IIS 安装及.net 4.5及Win10安装IIS并配置ASP.NET 4.0的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-22
- 这篇文章主要介绍了详解.NET Core 3.0 里新的JSON API,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
- 这篇文章主要介绍了.net数据库操作框架SqlSugar的简单入门,帮助大家更好的理解和学习使用.net技术,感兴趣的朋友可以了解下...2021-09-22
ASP.NET Core根据环境变量支持多个 appsettings.json配置文件
这篇文章主要介绍了ASP.NET Core根据环境变量支持多个 appsettings.json配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22- 这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
- ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口。这篇文章主要给大家介绍了.NET C#利用ZXing生成、识别二维码/条形码的方法,文中给出了详细的示例代码,有需要的朋友们可以参考借鉴。...2020-06-25
详解ASP.NET Core 中基于工厂的中间件激活的实现方法
这篇文章主要介绍了ASP.NET Core 中基于工厂的中间件激活的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-22- 这篇文章主要介绍了C#使用Ado.Net更新和添加数据到Excel表格的方法,较为详细的分析了OLEDB的原理与使用技巧,可实现较为方便的操作Excel数据,需要的朋友可以参考下...2020-06-25
asp.net通过消息队列处理高并发请求(以抢小米手机为例)
这篇文章主要介绍了asp.net通过消息队列处理高并发请求(以抢小米手机为例),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22- Underscore 是一个 JavaScript 工具库,它提供了一整套函数式编程的实用功能,但是没有扩展任何 JavaScript 内置对象。这篇文章主要介绍了underscore源码分析相关知识,感兴趣的朋友一起学习吧...2016-01-02
ASP.NET单选按钮控件RadioButton常用属性和方法介绍
RadioButton又称单选按钮,其在工具箱中的图标为 ,单选按钮通常成组出现,用于提供两个或多个互斥选项,即在一组单选钮中只能选择一个...2021-09-22ASP.NET 2.0中的数据操作:使用两个DropDownList过滤的主/从报表
在前面的指南中我们研究了如何显示一个简单的主/从报表, 该报表使用DropDownList和GridView控件, DropDownList填充类别,GridView显示选定类别的产品. 这类报表用于显示具有...2016-05-19详解.NET Core 使用HttpClient SSL请求出错的解决办法
这篇文章主要介绍了.NET Core 使用HttpClient SSL请求出错的解决办法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2021-09-22- 这篇文章主要介绍了Python调用.NET库的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-05-09
ASP.NET中iframe框架点击左边页面链接 右边显示链接页面内容
这篇文章主要介绍了ASP.NET中iframe框架点击左边页面链接,右边显示链接页面内容的实现代码,感兴趣的小伙伴们可以参考一下...2021-09-22- ASP.NET Web API具有与ASP.NET MVC类似的编程方式,ASP.NET Web API不仅仅具有一个完全独立的消息处理管道,而且这个管道比为ASP.NET MVC设计的管道更为复杂,功能也更为强大。下面创建一个简单的Web API项目,需要的朋友可以参考下...2021-09-22
- 这篇文章主要介绍了ASP.NET连接MySql数据库的2个方法及示例,使用的是MySQL官方组件和ODBC.NET,需要的朋友可以参考下...2021-09-22