Unity中C#如何执行cmd命令(System.Diagnostics.Process的使用)
发布日期:2021-06-30 19:38:59 浏览次数:3 分类:技术文章

本文共 6385 字,大约阅读时间需要 21 分钟。

在Unity中,我们可能需要自己写Editor工具。有时候我们可能还需要执行外部指令或者脚本(比如python脚本),这个时候,就需要用c#的System.Diagnostics.Process这个类了。

 

命名空间

using System.Diagnostics;

Process.Star()的构造方法

名称 说明
Process.Start () 启动(或重用)此 Process 组件的 StartInfo 属性指定的进程资源,并将其与该组件关联。
Process.Start (ProcessStartInfo) 启动由包含进程启动信息(例如,要启动的进程的文件名)的参数指定的进程资源,并将该资源与新的 Process 组件关联。
Process.Start (String) 通过指定文档或应用程序文件的名称来启动进程资源,并将资源与新的 Process 组件关联。
Process.Start (String, String) 通过指定应用程序的名称和一组命令行参数来启动一个进程资源,并将该资源与新的 Process 组件相关联。
Process.Start (String, String, SecureString, String) 通过指定应用程序的名称、用户名、密码和域来启动一个进程资源,并将该资源与新的 Process 组件关联起来。
Process.Start (String, String, String, SecureString, String) 通过指定应用程序的名称和一组命令行参数、用户名、密码和域来启动一个进程资源,并将该资源与新的 Process 组件关联起来。

简单的接口封装

public static void RunCmd(string cmd, string args, string workdir=null){    string[] res = new string[2];    var p = CreateCmdProcess (cmd, args, workdir);    res [0] = p.StandardOutput.ReadToEnd ();    res [1] = p.StandardError.ReadToEnd ();    p.Close ();    return res;}public static System.Diagnostics.Process CreateCmdProcess(string cmd, string args, string workdir=null){    var pStartInfo = new System.Diagnostics.ProcessStartInfo (cmd);    pStartInfo.Arguments = args;    pStartInfo.CreateNoWindow = false;    pStartInfo.UseShellExecute = false;    pStartInfo.RedirectStandardError = true;    pStartInfo.RedirectStandardInput = true;    pStartInfo.RedirectStandardOutput = true;    pStartInfo.StandardErrorEncoding = System.Text.UTF8Encoding.UTF8;    pStartInfo.StandardOutputEncoding= System.Text.UTF8Encoding.UTF8;    if(!string.IsNullOrEmpty(workdir))        pStartInfo.WorkingDirectory = workdir;    return System.Diagnostics.Process.Start(pStartInfo);}

调用,假设我们想执行svn update的指令

var path = "D:\\Project\\";RunCmd ("svn", string.Format("update \"{0}\"", path));

关于WorkingDirectory属性

WorkingDirectory属性指定可执行文件的位置。

如果WorkingDirectory是空字符串,则认为当前目录以包含可执行文件。

假设我们有一个py脚本test.py在D盘的py_pro目录中,即   D:\\py_pro\\test.py

我们要执行这个脚本,需要这样子

var workdir= "D:\\py_pro\\";RunCmd ("python", workdir + "test.py", workdir);

更多例子 

// 打开记事本System.Diagnostics.Process.Start("notepad.exe");        // 打开计算器System.Diagnostics.Process.Start("calc.exe ");                // 打开注册表System.Diagnostics.Process.Start("regedit.exe ");           // 打开画图板System.Diagnostics.Process.Start("mspaint.exe ");        // 打开写字板System.Diagnostics.Process.Start("write.exe ");              // 打开播放器System.Diagnostics.Process.Start("mplayer2.exe ");        // 打开任务管理器System.Diagnostics.Process.Start("taskmgr.exe ");          // 打开事件查看器System.Diagnostics.Process.Start("eventvwr.exe ");          // 打开系统信息System.Diagnostics.Process.Start("winmsd.exe ");           // 打开Windows版本信息System.Diagnostics.Process.Start("winver.exe ");              // 发邮件System.Diagnostics.Process.Start("mailto: "+ address);    

接口封装(详细版):

using System;using UnityEditor;using UnityEngine;using System.Collections.Generic;using System.IO;using System.Threading;using System.Text;class EdtUtil{    ///     /// 构建Process对象,并执行    ///     /// 命令    /// 命令的参数    /// 工作目录    /// 
Process对象
private static System.Diagnostics.Process CreateCmdProcess(string cmd, string args, string workingDir = "") { var en = System.Text.UTF8Encoding.UTF8; if (Application.platform == RuntimePlatform.WindowsEditor) en = System.Text.Encoding.GetEncoding("gb2312"); var pStartInfo = new System.Diagnostics.ProcessStartInfo(cmd); pStartInfo.Arguments = args; pStartInfo.CreateNoWindow = false; pStartInfo.UseShellExecute = false; pStartInfo.RedirectStandardError = true; pStartInfo.RedirectStandardInput = true; pStartInfo.RedirectStandardOutput = true; pStartInfo.StandardErrorEncoding = en; pStartInfo.StandardOutputEncoding = en; if (!string.IsNullOrEmpty(workingDir)) pStartInfo.WorkingDirectory = workingDir; return System.Diagnostics.Process.Start(pStartInfo); } /// /// 运行命令,不返回stderr版本 /// /// 命令 /// 命令的参数 /// 工作目录 ///
命令的stdout输出
public static string RunCmdNoErr(string cmd, string args, string workingDri = "") { var p = CreateCmdProcess(cmd, args, workingDri); var res = p.StandardOutput.ReadToEnd(); p.Close(); return res; } /// /// 运行命令,不返回stderr版本 /// /// 命令 /// 命令的参数 /// StandardInput /// 工作目录 ///
命令的stdout输出
public static string RunCmdNoErr(string cmd, string args, string[] input, string workingDri = "") { var p = CreateCmdProcess(cmd, args, workingDri); if (input != null && input.Length > 0) { for (int i = 0; i < input.Length; i++) p.StandardInput.WriteLine(input[i]); } var res = p.StandardOutput.ReadToEnd(); p.Close(); return res; } /// /// 运行命令 /// /// 命令 /// 命令的参数 ///
string[] res[0]命令的stdout输出, res[1]命令的stderr输出
public static string[] RunCmd(string cmd, string args, string workingDir = "") { string[] res = new string[2]; var p = CreateCmdProcess(cmd, args, workingDir); res[0] = p.StandardOutput.ReadToEnd(); res[1] = p.StandardError.ReadToEnd(); #if !UNITY_IOS res[2] = p.ExitCode.ToString(); #endif p.Close(); return res; } /// /// 打开文件夹 /// /// 文件夹的绝对路径 public static void OpenFolderInExplorer(string absPath) { if (Application.platform == RuntimePlatform.WindowsEditor) RunCmdNoErr("explorer.exe", absPath); else if (Application.platform == RuntimePlatform.OSXEditor) RunCmdNoErr("open", absPath.Replace("\\", "/")); }}

使用

上面的RunCmd接口,return的string[],第0个是脚本的输出,第1个是错误输出

比如通过上面的RunCmd接口运行下面的python脚本

#python脚本: test.py, 放在Assets/python目录中print("Hello, I am python!")print("This is a test")try:    print(1/0)except BaseException,e:    print("Error: " + str(e))
//c# 通过RunCmd接口执行python脚本var workdir = Application.dataPath + "/python/";var results = EdtUtil.RunCmd("python", workdir + "test.py", workdir);Debug.Log("python output: " + results[0]);Debug.Log("python error: " + results[1]);

输出的结果是

python output: Hello, I am python!This is a testpython error: Error: integer division or module by zero

我们可以在c#根据python返回的结果进行判断然后抛出c#的异常:

// c#抛出异常if(results[0].LastIndexOf("Error") > 0){    throw new System.Exception("python Error");}

 

转载地址:https://linxinfa.blog.csdn.net/article/details/52982384 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Windows 的路径中表示文件层级为什么会用反斜杠 ‘\’,而 UNIX 系统都用斜杠 ‘/’?
下一篇:谈谈类之间的关联关系与依赖关系

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月16日 07时01分51秒