UnityEditor写工具编译项目

该代码段展示了如何在Unity编辑器中通过CMD调用Microsoft Visual Studio的LaunchDevCmd.bat文件来编译模块项目为DLL,并将其复制到主项目中供调用。首先,找到Visual Studio的安装路径,然后执行bat文件进行编译,最后将生成的DLL移动到Unity的指定目录并刷新AssetDatabase。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前提:项目中有需求,在项目里有一个主项目,一个模块项目,需要将模块项目编译成dll给主项目调用。

设计:

  • 寻找Microsoft visual studio目录
  • 调用LaunchDevCmd.bat.
  • Msbuild
  • copy target dll
  • refresh

用到的知识:

  • unity中开启cmd
  • 字符串编码格式转换
  • https://docs.microsoft.com/zh-cn/visualstudio/ide/reference/command-prompt-powershell?view=vs-2019
  • https://docs.microsoft.com/zh-cn/visualstudio/msbuild/msbuild-command-line-reference?view=vs-2019

GUI:在这里插入图片描述

#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;


public class CMD : EditorWindow
{
    [MenuItem("SDK/编译sdk %w")]
    private static void Msbuild()
    {
        var window = GetWindow<CMD>();
        window.Show();
        //window.Close();
        microsoftVisualPath = EditorPrefs.GetString(nameof(microsoftVisualPath));
    }

    private void Check()
    {
        //if()
        var batFile = Path.Combine(microsoftVisualPath, launchDevCMDPath);
        
        //entreprise
        if(File.Exists(batFile))
        {

            Rebuild(batFile);
        }
        //profession
        else if(File.Exists(batFile = batFile.Replace(enterprise, professional)))
        {
            Rebuild(batFile);
        }
        //community
        else if (File.Exists(batFile = batFile.Replace(professional, community)))
        {
            Rebuild(batFile);
        }
        else
        {
            this.ShowNotification(new GUIContent() { image = EditorGUIUtility.IconContent("d_Collab.FolderConflict").image, text = "请检查MicrosoftVisualStudio路径!" });
        }
        Debug.Log($"batFile:{batFile}");
    }

    private string output;
    private void Rebuild(string batFile)
    {
        output = string.Empty;

        Process proc = null;

        try
        {
            proc = new Process();
            proc.StartInfo.FileName = batFile;
            //proc.StartInfo.Arguments = string.Format("10");//this is argument
            proc.StartInfo.CreateNoWindow = false;
            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.RedirectStandardInput = true;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.RedirectStandardError = true;
            
            proc.Start(); 

            string strInput = "chcp 65001" + @"\" + "echo 输入编译命令!" + @"\";
            proc.StandardInput.WriteLine(strInput);
            proc.StandardInput.AutoFlush = true;
            strInput = "chcp 65001" + "&msbuild E:\\sw\\Unity_project\\AFEvent\\AstralSDK\\AstralSDK.csproj /t:ResolveReferences;Compile  /p:Configuration=Release" + @"\" + "&exit";
            proc.StandardInput.WriteLine(strInput);
            proc.StandardInput.AutoFlush = true;
            output = proc.StandardOutput.ReadToEnd();

            Encoding gbkencoding = Encoding.GetEncoding(936);
            byte[] buf2 = Encoding.Convert(gbkencoding, Encoding.UTF8, System.Text.Encoding.Default.GetBytes(output));
            string atext = Encoding.UTF8.GetString(buf2);

            proc.WaitForExit();

            

        }
        catch (Exception ex)
        {
            Debug.LogErrorFormat("Exception Occurred :{0},{1}", ex.Message, ex.StackTrace);
        }
        Debug.Log($"batFile:执行完成!");

        //move dll
        var filePath = Path.Combine(System.IO.Directory.GetCurrentDirectory(), "AstralSDK", "obj", "Release", "net472", "AstralSDK.dll");
        var destPath = Path.Combine(Application.dataPath, "SDK", "AstralSDK.dll");
        if(File.Exists(destPath))
        {
            FileUtil.DeleteFileOrDirectory(destPath);
            FileUtil.DeleteFileOrDirectory(destPath + ".meta");
        }
        AssetDatabase.Refresh();
        FileUtil.CopyFileOrDirectory(filePath, destPath);
        Debug.Log($"batFile:移动完成!");
        AssetDatabase.Refresh();
    }
 

    private static string microsoftVisualPath;
    private string launchDevCMDPath = "2019\\Enterprise\\Common7\\Tools\\LaunchDevCmd.bat";
    private string professional = "Professional";
    private string enterprise = "Enterprise";
    private string community = "Community";
    //private string astralSDKPath = "";
    private  Vector2 posScroll= Vector2.zero;
    private void OnGUI()
    {

        EditorGUILayout.LabelField("MicrosoftVisualStudio路径:" ,microsoftVisualPath,new GUIStyle(EditorStyles.boldLabel) {  alignment = TextAnchor.MiddleRight});

        if(GUILayout.Button("microsoftVisualStudioPath"))
        {
            microsoftVisualPath = EditorUtility.OpenFolderPanel("选择MicrosoftVisualStudio路径", microsoftVisualPath, "");
            EditorPrefs.SetString(nameof(microsoftVisualPath), microsoftVisualPath);
            //Debug.Log(new DirectoryInfo(Path.Combine(Application.dataPath, "..")).FullName);
            //Debug.Log();
        }

        if(GUILayout.Button("编译"))
        {
            if(string.IsNullOrWhiteSpace(microsoftVisualPath) || !microsoftVisualPath.Contains("Microsoft Visual Studio") || !Directory.Exists(microsoftVisualPath))
            {
                this.ShowNotification(new GUIContent() { image = EditorGUIUtility.IconContent("d_Collab.FolderConflict").image, text = "请检查MicrosoftVisualStudio路径!" });
                return;
            }
            Check();
        }

        posScroll = GUILayout.BeginScrollView(posScroll);
        GUILayout.TextArea(output);
        GUILayout.EndScrollView();
        
        if(GUILayout.Button("清理"))
        {
            output = string.Empty;
        }
    }



    
}
#endif


#编译.sln

#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;


public class CMD : EditorWindow
{
    [MenuItem("SDK/编译sdk %w")]
    private static void Msbuild()
    {
        var window = GetWindow<CMD>();
        window.Show();
        //window.Close();
        microsoftVisualPath = EditorPrefs.GetString(nameof(microsoftVisualPath));
    }

    private void Check()
    {
        //if()
        var batFile = Path.Combine(microsoftVisualPath, launchDevCMDPath);
        
        //entreprise
        if(File.Exists(batFile))
        {

            Rebuild(batFile);
        }
        //profession
        else if(File.Exists(batFile = batFile.Replace(enterprise, professional)))
        {
            Rebuild(batFile);
        }
        //community
        else if (File.Exists(batFile = batFile.Replace(professional, community)))
        {
            Rebuild(batFile);
        }
        else
        {
            this.ShowNotification(new GUIContent() { image = EditorGUIUtility.IconContent("d_Collab.FolderConflict").image, text = "请检查MicrosoftVisualStudio路径!" });
        }
        Debug.Log($"batFile:{batFile}");
    }

    private string output;
    private void Rebuild(string batFile)
    {
        output = string.Empty;

        Process proc = null;

        try
        {
            proc = new Process();
            proc.StartInfo.FileName = batFile;
            proc.StartInfo.Arguments = "/cipconfig";//this is argument
            proc.StartInfo.CreateNoWindow = false;
            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.RedirectStandardInput = true;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.RedirectStandardError = true;
            
            proc.Start();
            var path =Path.Combine(System.IO.Directory.GetCurrentDirectory(), "SDK", "SDK.sln");
            string strInput = "chcp 65001" + @"\" + "echo 输入编译命令!";
            proc.StandardInput.WriteLine(strInput);
            proc.StandardInput.AutoFlush = true;
            //strInput = "cd " + Path.Combine(System.IO.Directory.GetCurrentDirectory(), "SDK");
            //proc.StandardInput.WriteLine(strInput);
            //proc.StandardInput.AutoFlush = true;
            strInput = "chcp 65001" + "&msbuild " + path + " /t:Rebuild&exit";
            proc.StandardInput.WriteLine(strInput);
            proc.StandardInput.AutoFlush = true;
            output = proc.StandardOutput.ReadToEnd();

            Encoding gbkencoding = Encoding.GetEncoding(936);
            byte[] buf2 = Encoding.Convert(gbkencoding, Encoding.UTF8, System.Text.Encoding.Default.GetBytes(output));
            string atext = Encoding.UTF8.GetString(buf2);

            proc.WaitForExit();
            proc.Close();


        }
        catch (Exception ex)
        {
            Debug.LogErrorFormat("Exception Occurred :{0},{1}", ex.Message, ex.StackTrace);
        }
        Debug.Log($"batFile:执行完成!");

        //move dll
        var filePath = Path.Combine(System.IO.Directory.GetCurrentDirectory(), "SDK", "bin", "Release", "net471", "SDK.dll");
        var destPath = Path.Combine(Application.dataPath, "Plugins", "AstralSDK", "SDK.dll");
        var destSDKEditorPath = Path.Combine(Application.dataPath, "Plugins", "AstralSDK", "SDKEditor.dll");
        var fileSDKEditorPath = Path.Combine(System.IO.Directory.GetCurrentDirectory(), "SDK", "bin", "Release", "net471", "SDKEditor.dll");
        if (File.Exists(destPath))
        {
            FileUtil.DeleteFileOrDirectory(destPath);
            //FileUtil.DeleteFileOrDirectory(destPath + ".meta");
        }

        if(File.Exists(destSDKEditorPath))
        {
            FileUtil.DeleteFileOrDirectory(destSDKEditorPath);
            //FileUtil.DeleteFileOrDirectory(destSDKEditorPath + ".meta");
        }

        AssetDatabase.Refresh();
        FileUtil.CopyFileOrDirectory(filePath, destPath);
        FileUtil.CopyFileOrDirectory(fileSDKEditorPath, destSDKEditorPath);
        Debug.Log($"batFile:移动完成!");
        AssetDatabase.Refresh();
    }
 

    private static string microsoftVisualPath;
    private string launchDevCMDPath = "2019\\Enterprise\\Common7\\Tools\\LaunchDevCmd.bat";
    private string professional = "Professional";
    private string enterprise = "Enterprise";
    private string community = "Community";
    //private string astralSDKPath = "";
    private  Vector2 posScroll= Vector2.zero;
    private void OnGUI()
    {

        EditorGUILayout.LabelField("MicrosoftVisualStudio路径:" ,microsoftVisualPath,new GUIStyle(EditorStyles.boldLabel) {  alignment = TextAnchor.MiddleRight});

        if(GUILayout.Button("microsoftVisualStudioPath"))
        {
            microsoftVisualPath = EditorUtility.OpenFolderPanel("选择MicrosoftVisualStudio路径", microsoftVisualPath, "");
            EditorPrefs.SetString(nameof(microsoftVisualPath), microsoftVisualPath);
            //Debug.Log(new DirectoryInfo(Path.Combine(Application.dataPath, "..")).FullName);
            //Debug.Log(System.IO.Directory.GetCurrentDirectory());
        }

        if(GUILayout.Button("编译"))
        {
            if(string.IsNullOrWhiteSpace(microsoftVisualPath) || !microsoftVisualPath.Contains("Microsoft Visual Studio") || !Directory.Exists(microsoftVisualPath))
            {
                this.ShowNotification(new GUIContent() { image = EditorGUIUtility.IconContent("d_Collab.FolderConflict").image, text = "请检查MicrosoftVisualStudio路径!" });
                return;
            }
            Check();
        }

        posScroll = GUILayout.BeginScrollView(posScroll);
        GUILayout.TextArea(output);
        GUILayout.EndScrollView();
        
        if(GUILayout.Button("清理"))
        {
            output = string.Empty;
        }
    }



    
}
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

海尔辛

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

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

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

打赏作者

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

抵扣说明:

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

余额充值