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


在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("\\", "/"));
    }
}

接口封裝(詳細版):

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM