Unity中使用调用Shell的命令行

Unity中使用调用Shell的命令行

有的时候我们在做unity开发的时候需要去写一些工具编辑器之外的话通常会使用python,但有时也会使用shell命令行来完成一些操作,比如我们在写一自动化打包的时候 经常会使用一些linux指令来进行一些对文件或者文件夹的操作,这个时候使用shell就很实用。所以下面是一个shell的工具类来帮助我们可以在unity中更加轻松的使用 shell的一些指令。 c#代码如下:

using UnityEngine;
using System.Collections;
using System.Diagnostics;
using UnityEditor;
using System.Collections.Generic;

public class ShellHelper  {

	public class ShellRequest{
		public event System.Action<int,string> onLog;
		public event System.Action onError;
		public event System.Action onDone;

		public void Log(int type,string log){
			if(onLog != null){
				onLog(type,log);
			}
			if (type == 1) {
				UnityEngine.Debug.LogError (log);
			} else {
				UnityEngine.Debug.Log (log);
			}
		}

		public void NotifyDone(){
			if(onDone != null){
				onDone();
			}
		}

		public void Error(){
			if(onError != null){
				onError();
			}
		}
	}

	
	private static string shellApp{
		get{
			#if UNITY_EDITOR_WIN
			string app = "cmd.exe";
			#elif UNITY_EDITOR_OSX
			string app = "bash";
			#endif
			return app;
		}
	}


	private static List<System.Action> _queue = new List<System.Action>();


	static ShellHelper(){
		_queue = new List<System.Action>();
		EditorApplication.update += OnUpdate;
	}
	private static void OnUpdate(){
		for(int i = 0;i<_queue.Count;i++){
			try{
				var action = _queue[i];
				if(action != null){
					action();
				}
			}catch(System.Exception e){
				UnityEngine.Debug.LogException(e);
			}
		}
		_queue.Clear();
	}


	public static void ProcessCommandSync(string cmd, string workDirectory, Dictionary<string, string> envVars = null) {
		ProcessStartInfo start = new ProcessStartInfo(shellApp);

		#if UNITY_EDITOR_OSX
		start.Arguments = "-c";
		#elif UNITY_EDITOR_WIN
		start.Arguments = "/c";
		#endif

		if (envVars != null) {
			foreach (var kv in envVars) {
				if (start.EnvironmentVariables.ContainsKey(kv.Key)) {
					start.EnvironmentVariables[kv.Key] = kv.Value;
				} else {
					start.EnvironmentVariables.Add(kv.Key, kv.Value);
				}
			}
		}
		start.Arguments += (" \"" + cmd + " \"");
		start.CreateNoWindow = true;
		start.ErrorDialog = true;
		start.UseShellExecute = false;
		start.WorkingDirectory = workDirectory;
		start.RedirectStandardOutput = false;
		start.RedirectStandardError = false;
		start.RedirectStandardInput = false;
		Process p = Process.Start(start);
		p.WaitForExit();
		UnityEngine.Debug.LogFormat("Finish running {0}", cmd);
	}

    public static ShellRequest ProcessCommand(string cmd, string workDirectory, Dictionary<string, string> envVars = null, bool isSync = false){
		ShellRequest req = new ShellRequest();
		System.Threading.ThreadPool.QueueUserWorkItem(delegate(object state) {
			Process p = null;
			try{
				ProcessStartInfo start = new ProcessStartInfo(shellApp);

				#if UNITY_EDITOR_OSX
				start.Arguments = "-c";
				#elif UNITY_EDITOR_WIN
				start.Arguments = "/c";
				#endif
				
                if (envVars != null) {
                    foreach (var kv in envVars) {
						if (start.EnvironmentVariables.ContainsKey(kv.Key)) {
							start.EnvironmentVariables[kv.Key] = kv.Value;
						} else {
							start.EnvironmentVariables.Add(kv.Key, kv.Value);
						}
                    }
                }

				start.Arguments += (" \"" + cmd + " \"");
				start.CreateNoWindow = true;
				start.ErrorDialog = true;
				start.UseShellExecute = false;
				start.WorkingDirectory = workDirectory;

				if(start.UseShellExecute){ 
					start.RedirectStandardOutput = false;
					start.RedirectStandardError = false;
					start.RedirectStandardInput = false;
				} else{
					start.RedirectStandardOutput = true;
					start.RedirectStandardError = true;
					start.RedirectStandardInput = true;
					start.StandardOutputEncoding = System.Text.UTF8Encoding.UTF8;
					start.StandardErrorEncoding = System.Text.UTF8Encoding.UTF8;
				}

				p = Process.Start(start);
				p.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e) {
					UnityEngine.Debug.LogError(e.Data);
				};
				p.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) {
					UnityEngine.Debug.LogError(e.Data);
				};
				p.Exited += delegate(object sender, System.EventArgs e) {
					UnityEngine.Debug.LogError(e.ToString());
				};

				bool hasError = false;
				do{
					string line = p.StandardOutput.ReadLine();
					if(line == null){
						break;
					}
					line = line.Replace("\\","/");
						
					_queue.Add(delegate() {
						req.Log(0,line);
					});

				}while(true);

				while(true){
					string error = p.StandardError.ReadLine();
					if(string.IsNullOrEmpty(error)){
						break;
					}
					hasError = true;
					_queue.Add(delegate() {
						req.Log(1,error);
					});
				}
				p.Close();
				if(hasError){
					_queue.Add(delegate() {
						req.Error();
					});
				}
				else {
					_queue.Add(delegate() {
						req.NotifyDone();
					});
				} 

				
			}catch(System.Exception e){
				UnityEngine.Debug.LogException(e);
				if(p != null){
					p.Close();
				}
			}
		});
		return req;
	}

	
    private Dictionary<string, string> _enviroumentVars = new Dictionary<string, string>();
	
    public void AddEnvironmentVars(string key, string value){
        if (key == null || value == null)
            return;
        
        if (string.IsNullOrEmpty(key.Trim()))
            return;

        if (_enviroumentVars.ContainsKey(key))
            _enviroumentVars[key] = value;
        
        _enviroumentVars.Add(key, value);
	}

	public ShellRequest ProcessCMD(string cmd,string workDir){
		return ShellHelper.ProcessCommand(cmd,workDir,_enviroumentVars);
	}

}

例子:使用MSBuild编译出Dll

	[MenuItem("ILRuntime/拷贝Release Dll")]
	public static void CopyReleaseDll()
	{
		string msbuildPath = "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin";
       	string exe = "MSBuild.exe";
		string hotfixProject = Path.Combine(Environment.CurrentDirectory, "PlatformHotfix.csproj"); 
        ShellHelper.ProcessCommandSync($"\"{exe}\" \"{hotfixProject}\" /t:Clean,Build /p:configuration=\"release\"", msbuildPath);

		var folder = Path.GetDirectoryName(IL_HotFixFile_Dll1);
		
		if (!Directory.Exists(folder))
		{
			Directory.CreateDirectory(folder);
		}
		
		if (File.Exists(Release_HotfixDll1))
		{
			File.Copy(Release_HotfixDll1, IL_HotFixFile_Dll1, true);
			File.Copy(Release_HotfixPdb1, IL_HotFixFile_PDB1, true);
			Debug.Log($"成功复制 Hotfix.dll, Hotfix.pdb到 目录 " + folder);
			AssetDatabase.Refresh();
		}
	}

原文:https://tangmingcc.com/views/Unity%E5%AE%9E%E7%94%A8%E5%B7%A5%E5%85%B7/Unity%E4%B8%AD%E4%BD%BF%E7%94%A8%E8%B0%83%E7%94%A8Shell%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

KindSuper_liu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值