Unity中C#如何执行cmd命令(System.Diagnostics.Process的使用)

74 篇文章 29 订阅

在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
{
    /// <summary>
    /// 构建Process对象,并执行
    /// </summary>
    /// <param name="cmd">命令</param>
    /// <param name="args">命令的参数</param>
    /// <param name="workingDri">工作目录</param>
    /// <returns>Process对象</returns>
    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);
    }

    /// <summary>
    /// 运行命令,不返回stderr版本
    /// </summary>
    /// <param name="cmd">命令</param>
    /// <param name="args">命令的参数</param>
    /// <param name="workingDri">工作目录</param>
    /// <returns>命令的stdout输出</returns>
    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;
    }

    /// <summary>
    /// 运行命令,不返回stderr版本
    /// </summary>
    /// <param name="cmd">命令</param>
    /// <param name="args">命令的参数</param>
    /// <param name="input">StandardInput</param>
    /// <param name="workingDri">工作目录</param>
    /// <returns>命令的stdout输出</returns>
    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;
    }
	
    /// <summary>
    /// 运行命令
    /// </summary>
    /// <param name="cmd">命令</param>
    /// <param name="args">命令的参数</param>
    /// <returns>string[] res[0]命令的stdout输出, res[1]命令的stderr输出</returns>
    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;
    }
	
    /// <summary>
    /// 打开文件夹
    /// </summary>
    /// <param name="absPath">文件夹的绝对路径</param>
    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 test
python error: Error: integer division or module by zero

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

// c#抛出异常

if(results[0].LastIndexOf("Error") > 0)
{
    throw new System.Exception("python Error");
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林新发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值