.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 offdirecho "dotnet in Windows"

Linux: linux.sh

#!/bin/bashlsecho "dotnet in Linux"

OSX: OSX.sh

#!/bin/bashlsecho "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

原文地址: http://www.cnblogs.com/stulzq/p/9074965.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/321266.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nssl1458-HR 的疑惑【枚举】

正题 题目大意 给出nnn,求[1..n][1..n][1..n]中有多少个数可以被ab(b>1)a^b(b>1)ab(b>1)表示 解题思路 首先如果bbb等于222,那么可以被表示的数就是n\sqrt nn​个 bbb不是质数时,显然所以的数都可以被一个bbb是质数的情况表示。 …

性能是.NET Core的一个关键特性

关键要点.NET Core是跨平台的,可运行在Windows、Linux、Mac OS X和更多平台上;与.NET相比,发布周期要短得多。大多数.NET Core 都是通过NuGet软件包交付的,可以很容易地发布和升级。更快速的发布周期对性能提升工作以及改进诸如So…

简单的数学问题 洛谷 P1414 又是毕业季II

题意 给出n个数字,询问从中挑出k个数字,最大可能的公共gcd是多少。 题解 k个数的gcd一定出现至少k次。 我们遍历所有的数并对每个数字求它所有的因子,统计各个因子出现的个数。 给定k时,我们的答案就是所有出现次数>k的因…

【枚举】连续自然数和(jzoj 2102)

连续自然数和 题目大意&#xff1a; 输出一个n&#xff0c;求出所有相加等于n的连续自然数序列 样例输入 10000 样例输出 18 142 297 328 388 412 1998 2002 数据范围限制 10 < M < 2,000,000 解题思路&#xff1a; 这道题的正解的时间复杂度是o(2n)o\left …

nssl1460-逛机房【bfs】

正题 题目大意 nnn次询问&#xff0c;给出一个数xxx&#xff0c;每次可以进行操作 修改其中一个位&#xff0c;去掉前导零删掉其中一个位&#xff0c;去掉前导零 询问最少步骤使得xxx变为一个完全平方数 解题思路 我们可以从完全平方数开始广搜&#xff0c;操作变为 加入一…

将 ASP.NET Core 2.0 项目升级至 ASP.NET Core 2.1 RC 1

微软发布了 .NET Core 2.1 RC 1 &#xff0c;虽然只是 Release Candidate 版&#xff0c;但已经可以在生产环境中使用。NET Core 2.1 RC is supported by Microsoft and can be used in production..NET Core 2.1 的性能大提升早让人垂涎三尺&#xff0c;看到这个消息后&#x…

洛谷P1169 树上分组背包

题解 第一次写树上分组背包的题目。 什么是分组背包&#xff1f; 分组背包就是将物品进行分组每组内部只能选择一类物品。 for(int i 1;i < N;i){for(int j 0;j < V;j){for(int k 0;k < item[I];k){dp[i][j] max(dp[i][j],dp[i-1][j-v[i][k]]w[i][k]); }} …

【dfs】简单游戏(jzoj 2121)

简单游戏 题目大意 原本有n个数字&#xff0c;第1,2个相加&#xff0c;第2&#xff0c;3个相加……第n-1,n个相加&#xff0c;由此得出一个长度为n-1的新序列&#xff0c;然后不停重复&#xff0c;最后得出一个t&#xff0c;现在给出一开始的n和t求符合的序列&#xff08;字典…

nssl1459-空间简单度【扫描线,线段树】

正题 题目大意 nnn个点的一颗树&#xff0c;合法路径定义为一条路径上每个点的编号相差大于KKK。求合法路径数 解题思路 首先我们可以求不合法的路径数&#xff0c;这样我们就有了K∗nK*nK∗n个不合法&#xff08;即不能在同一个路径上&#xff09;的点对。 然后这题就和之前…

ASP.NET Core Identity Hands On(2)——注册、登录、Claim

上一篇文章&#xff08;ASP.NET Core Identity Hands On&#xff08;1&#xff09;——Identity 初次体验&#xff09;中&#xff0c;我们初识了Identity&#xff0c;并且详细分析了AspNetUsers用户存储表&#xff0c;这篇我们将一起学习Identity 默认生成的样板代码的注册与登…

洛谷 动态规划一日游 P2577、P1070、P2051

记 2018年3月19日 贼颓呢&#xff0c;一天就写了两道DP&#xff0c;还都不会写&#xff0c;这可GG。 动态规划真的难且有趣&#xff0c;算法题中动态规划占到了很大的比例&#xff0c;而且动态规划往往是辅助解决一些其他类型问题的基础&#xff0c;加深加强对动态规划问题的…

【DP】【高精】幸运票 (jzoj 2122)

幸运票 题目大意&#xff1a; 一个长度为2N的序列&#xff0c;这些数的总和为S&#xff0c;当这个序列的前N个和后N个总和相等时&#xff0c;它是符合题意的&#xff0c;问有符合题意的有多少种可能 样例输入 2 2 样例输出 4 数据范围限制 1<N<50 S<1000 解…

51nod-有限背包计数问题【dp】

正题 题目链接:http://www.51nod.com/Challenge/Problem.html#problemId1597 题目大意 nnn种物品&#xff0c;第iii个大小为iii且有iii个。 求恰好填满大小为nnn的背包的方案数 解题思路 我们可以将背包分为两份&#xff0c;对于大小小于等于n\sqrt nn​的物品&#xff0c;这…

Build 2018大会:.NET概述和路线图

在Microsoft Build 2018大会上&#xff0c;.NET项目管理主管Scott Hunter和.NET社区主管Scott Hanselman举行了一场有关.NET未来发展的会谈。会谈指出&#xff0c;未来.NET平台将可以搭建任何类型的应用程序&#xff1a;桌面程序、web程序、云程序、移动应用、游戏应用、物联网…

洛谷P2278操作系统 模拟+堆

一道模拟题 竟然活生生的不会模拟&#xff0c;感觉自己好菜啊。 在模拟的时候&#xff0c;一定要弄清楚要对什么进行模拟。 题解 进程的等待队列是一个优先队列&#xff0c;优先队列是以优先级降序作为第一关键字&#xff0c;以进入时间为第二关键字。在操作系统这道题目中…

【二分】抄书 (jzoj 2123)

抄书 题目大意&#xff1a; 有n本书&#xff0c;分给m个人抄&#xff0c;每个人只能拿到连续的书&#xff08;不能把一本书分开&#xff09;&#xff0c;问抄书最多的人要抄多少页 样例输入 9 3 100 200 300 400 500 600 700 800 900 样例输出 1700 数据范围限制 对于…

nssl1467-U【差分】

正题 题目大意 n∗nn*nn∗n的矩阵&#xff0c;每次让一个下三角形内数字加上一定权值。求最后所有位置的异或和 解题思路 我们发现如果我们对于没行做前缀和的话&#xff0c;我们需要修改的位置就是一个竖直下去的一列和斜着的一条&#xff0c;所以我们可以分别对于竖着的和斜…

汽车之家汽车品牌Logo信息抓取 DotnetSpider实战[三]

一、正题前的唠叨第一篇实战博客&#xff0c;阅读量1000&#xff0c;第二篇&#xff0c;阅读量200&#xff0c;两篇文章相差近5倍&#xff0c;这个差异真的令我很费劲&#xff0c;截止今天&#xff0c;我一直在思考为什么会有这么大的差距&#xff0c;是因为干货变少了&#xf…

洛谷P1801 黑匣子 双堆套路的使用

题意 题目链接 题解 这道题本可以用Treap暴力求解出来&#xff0c;但是不够优雅&#xff0c;因为没有充分利用到题目中给的条件&#xff0c;那就是要求的ithith小的值的ii是单调递增的。我们用两个堆来维护,大顶堆和小顶堆。 大顶堆中的元素是排好序的前i&#x2212;1&qu…

2019.01.26【NOIP普及组】模拟赛C组总结

总结 这次比赛的得分是&#xff1a;10001060170 第一题想了一会&#xff0c;想到了方法&#xff0c;直接打出来&#xff0c;第二题不会&#xff0c;想水分&#xff0c;但没水到&#xff0c;第三题打了一个假的DP&#xff0c;10分&#xff0c;第四题用DP超时了&#xff0c;60分…