美文网首页U3D技术采集Unity基础
Unity调用外部Shell脚本或exe

Unity调用外部Shell脚本或exe

作者: 游戏开发小Y | 来源:发表于2017-03-22 10:20 被阅读234次

    有时候项目里需要执行一些shell脚本,来完成诸如文件移动,命令行打包,自己转换文件
    格式什么的工作,省去一些手工劳动,然后这时候就需要用shell了。
    网上也有一些关于调用方法的文章,这里就说一下我自己尝试时遇到的问题。


    讲到c#里操作进程的方法,那肯定就是System.Diagnostics.Process这个类没跑了

    代码如下:

    01.using UnityEngine;  
    02.using UnityEditor;  
    03.using System.Diagnostics;  
    04.using System.Threading;  
    05.using System.IO;  
    06.  
    07.public class TestRunShell : ScriptableObject  
    08.{  
    09.    [MenuItem("Menu/RunShell")]  
    10.    public static void RunShell()  
    11.    {  
    12.        // 这里不开线程的话,就会阻塞住unity的主线程,当然如果你需要阻塞的效果的话可以不开  
    13.        Thread newThread = new Thread(new ThreadStart(RunShellThreadStart));  
    14.        newThread.Start();  
    15.    }  
    16.  
    17.    private static void RunShellThreadStart()  
    18.    {  
    19.        string cmdTxt = @"echo test  
    20.notepad C:\Users\pc\Desktop\1.txt  
    21.explorer.exe D:\  
    22.pause";  
    23.  
    24.        RunCommand(cmdTxt);  
    25.        //RunProcessCommand("notepad", @"C:\Users\pc\Desktop\1.txt");  
    26.        //RunProcessCommand("explorer.exe", @"D:\");  
    27.    }  
    28.  
    29.    private static void RunCommand(string command)  
    30.    {  
    31.        Process process = new Process();  
    32.        process.StartInfo.FileName = "powershell";  
    33.        process.StartInfo.Arguments = command;  
    34.  
    35.        process.StartInfo.CreateNoWindow = false; // 获取或设置指示是否在新窗口中启动该进程的值(不想弹出powershell窗口看执行过程的话,就=true)  
    36.        process.StartInfo.ErrorDialog = true; // 该值指示不能启动进程时是否向用户显示错误对话框  
    37.        process.StartInfo.UseShellExecute = false;  
    38.        //process.StartInfo.RedirectStandardError = true;  
    39.        //process.StartInfo.RedirectStandardInput = true;  
    40.        //process.StartInfo.RedirectStandardOutput = true;  
    41.  
    42.        process.Start();  
    43.  
    44.        //process.StandardInput.WriteLine(@"explorer.exe D:\");  
    45.        //process.StandardInput.WriteLine("pause");  
    46.  
    47.        process.WaitForExit();  
    48.        process.Close();  
    49.    }  
    50.  
    51.    private static void RunProcessCommand(string command, string argument)  
    52.    {  
    53.        ProcessStartInfo start = new ProcessStartInfo();  
    54.        start.FileName = command;  
    55.        start.Arguments = argument;  
    56.  
    57.        start.CreateNoWindow = false;  
    58.        start.ErrorDialog = true;  
    59.        start.UseShellExecute = false;  
    60.  
    61.        Process p = Process.Start(start);  
    62.        p.WaitForExit();  
    63.        p.Close();  
    64.    }  
    65.}  
    

    用 cmd.exe 执行的问题

    因为我是windows环境,且搜到的文章里都是

    process.StartInfo.FileName = "cmd.exe";1
    1

    这样的写法,但是经过测试发现,在cmd里能够执行的命令,传不进cmd.exe里面去,怀疑是不是mono的事,.net下可能就传进去了,这里懒得深究了。。。
    但是换成powershell就可以很顺利的传进去执行。

    我手上没有mac的环境,但是感觉把powershell换成bash,应该就可以在mac上顺利的执行shell脚本了


    ProcessStartInfo的RedirectStandardError,RedirectStandardInput,RedirectStandardOutput属性的设置问题

    msdn上查的UseShellExecute的说明

    若要在启动进程时使用外壳程序,则为 true;否则,直接从可执行文件创建进程。默认为 true。

    将此属性设置为 false 使您能够重定向输入流、输出流和错误流。
    测试结果:
    ①,UseShellExecute = false,3个重定向的设置为true时,打开的shell窗口中,我们就看不到echo 看我!这样命令的输出结果了。

    ②,UseShellExecute = true,他们3个也是true时,传入的shell脚本不能够运行。

    ③,3个重定向的属性为true时,我们并不能用截取输入流的方式往里面传入参数
    例如:

    01.process.Start();  
    02.process.StandardInput.WriteLine(@"explorer.exe D:\");  
    03.process.StandardInput.WriteLine("pause");  
    04.process.WaitForExit();  
    05.process.Close();  
    

    所以总结一下就是,那3个重定向属性还是保持默认值就好了,反正往输入流中写参数的方法也不管用,
    使用的时候,我们就可以先把自己写的.bat文件读成字符串,然后用上面的RunCommand执行整个bat脚本了。
    还可以用RunProcessCommand方法去调用指定的.exe,并为其传递参数了(前提是它能接收参数)

    推荐:http://blog.csdn.net/kakashi8841/article/details/44998241

    相关文章

      网友评论

        本文标题:Unity调用外部Shell脚本或exe

        本文链接:https://www.haomeiwen.com/subject/uiznnttx.html