使用.NET Core怎么跨平台执行命令、脚本
创始人
2024-11-27 19:03:13
0次

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执行会收到下面的信息:

使用.NET Core怎么跨平台执行命令、脚本

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}");
 }
}

执行结果如下:

使用.NET Core怎么跨平台执行命令、脚本

从执行结果可以看出,我们通过编写的程序来执行dotnet --info命令获取的结果几乎一样,只有第一行的提示,我们通过cmd执行命令输出的是中文,我们通过程序调用执行输出的是英文,这个问题,有兴趣的朋友可以研究一下。

2.在Linux上执行

使用的系统环境为CentOS 7.2,.NET Core sdk版本为2.0.3。

直接执行命令结果如下:

使用.NET Core怎么跨平台执行命令、脚本

我将代码上传到git server,然后在linux上clone然后执行结果如下:

使用.NET Core怎么跨平台执行命令、脚本

可以看到我们获取执行输出是没有问题的,但是获取进程开始执行出错了,无法从进程检索该信息,现在我们移除统计执行时间的代码:

使用.NET Core怎么跨平台执行命令、脚本

这下我们执行就没有问题了。从这里我们可以得出结论:由于平台的差异,获取一些信息可能会出现异常,所以我们实际一定要在多个平台上测试。

3.在OSX上运行

我在OSX上的.NET Core SDK版本为2.0.0 很久没更新了。

直接执行命令:

使用.NET Core怎么跨平台执行命令、脚本

从git Clone代码,执行结果如下:

使用.NET Core怎么跨平台执行命令、脚本

可以看出我们在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 文件夹下。

使用.NET Core怎么跨平台执行命令、脚本

因为我们需要根据不同的操作类型,选择不同的脚本来进行执行,所以我们需要在代码里面判断一下操作系统类型。我们可以通过 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下运行

使用.NET Core怎么跨平台执行命令、脚本

在windows下运行是完全正常的。

4.在OSX运行

直接运行会报一个权限异常,如下:

使用.NET Core怎么跨平台执行命令、脚本

使用命令加入执行权限:

chmod +x OSX.sh

然后再次执行:

使用.NET Core怎么跨平台执行命令、脚本

可以看到成功执行了脚本。

5.在Linux上运行

直接运行也是会有权限问题的:

使用.NET Core怎么跨平台执行命令、脚本

同样使用命令加入执行权限:

chmod +x linux.sh

然后再次执行:

使用.NET Core怎么跨平台执行命令、脚本

可以看到成功执行了我们的脚本。

4.容易犯的错误

看见上面的例子,我都成功执行了,其实我踩了几个坑,花了我不少时间来解决。

1.sh脚本一定要指定命令解析器

也就是这句话,放在sh脚本开头

#!/bin/bash

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...