public DllBuild(string outputDir) { _outputDir = outputDir; if (false == Directory.Exists(outputDir)) { Directory.CreateDirectory(outputDir); } _outputAssemblyPath = FileTool.CombinePaths(outputDir, LWUtility.HotfixFileName); }
private static void GenAdapterRegisterFile(List <Type> _types, string dir) { string fileHeader = @" using System; using System.Collections; using System.Collections.Generic; using ILRuntime.CLR.Method; using ILRuntime.Runtime.Enviorment; using ILRuntime.Runtime.Intepreter; public class AdapterRegister { public static void RegisterCrossBindingAdaptor(ILRuntime.Runtime.Enviorment.AppDomain domain) { //这几条是手写的 domain.RegisterCrossBindingAdaptor(new MonoBehaviourAdapter()); domain.RegisterCrossBindingAdaptor(new CoroutineAdapter()); //以下是自动生成的 "; string lines = "\r\n"; foreach (var t in _types) { string line = @" domain.RegisterCrossBindingAdaptor(new " + t.Name.Replace("`", "_") + "Adapter());\r\n"; lines += line; } string outputString = fileHeader + lines + @" } }"; FileStream file = null; StreamWriter sw = null; //有什么错误,就直接让系统去抛吧。 //file = new FileStream(IPath.Combine( dir ,"AdapterRegister.cs"), FileMode.Create); file = new FileStream(FileTool.CombinePaths(dir, "AdapterRegister.cs"), FileMode.Create); sw = new StreamWriter(file); sw.Write(outputString); sw.Flush(); sw.Close(); file.Close(); }
/// <summary> /// 加载Dll热更脚本 /// </summary> /// <param name="root">路径</param> /// <param name="mode"></param> /// <returns></returns> public IEnumerator IE_LoadScript(HotfixCodeRunMode mode) { string dllPath = ""; if (Application.isEditor) { //这里情况比较复杂,Mobile上基本认为Persistent才支持File操作, dllPath = Application.streamingAssetsPath + "/Hotfix/" + LWUtility.HotfixFileName; } else { //这里情况比较复杂,Mobile上基本认为Persistent才支持File操作, //可寻址目录也只有 StreamingAsset var firstPath = FileTool.CombinePaths(LWUtility.updatePath, LWUtility.HotfixFileName); //LWUtility.updatePath + "/" + LWUtility.HotfixFileName; var secondPath = FileTool.CombinePaths(Application.streamingAssetsPath, LWUtility.AssetBundles, LWUtility.GetPlatform(), LWUtility.HotfixFileName); // Application.streamingAssetsPath + "/" + LWUtility.AssetBundles + "/" + LWUtility.GetPlatform() + "/" + LWUtility.HotfixFileName; if (!File.Exists(firstPath)) { var request = UnityWebRequest.Get(secondPath); LWDebug.Log("firstPath:" + firstPath); LWDebug.Log("secondPath:" + secondPath); yield return(request.SendWebRequest()); if (request.isDone && request.error == null) { LWDebug.Log("request.downloadHandler.data:" + request.downloadHandler.data.Length); LWDebug.Log("拷贝dll成功:" + firstPath); byte[] results = request.downloadHandler.data; FileTool.WriteByteToFile(firstPath, results, ""); } } dllPath = firstPath; } LWDebug.Log("Dll路径:" + dllPath); //反射执行 if (mode == HotfixCodeRunMode.ByReflection) { var bytes = File.ReadAllBytes(dllPath); var mdb = dllPath + ".mdb"; if (File.Exists(mdb)) { var bytes2 = File.ReadAllBytes(mdb); Assembly = Assembly.Load(bytes, bytes2); } else { Assembly = Assembly.Load(bytes); } //Debug.Log("反射模式,开始执行Start"); //var type = Assembly.GetType("StartupBridge_Hotfix"); //var method = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static); //method.Invoke(null, new object[] { false }); StartupBridge_Hotfix.StartReflection(Assembly); } #if ILRUNTIME //解释执行 else if (mode == HotfixCodeRunMode.ByILRuntime) { //解释执行模式 // ILRuntimeHelper.LoadHotfix(dllPath); // ILRuntimeHelper.AppDomain.Invoke("StartupBridge_Hotfix", "Start", null, new object[] { true }); } #endif else if (mode == HotfixCodeRunMode.ByCode) { LWDebug.Log("内置code模式!", LogColor.green); StartupBridge_Hotfix.StartCode(); //反射调用,防止编译报错 //Assembly assembly = Assembly.GetExecutingAssembly(); //var type = assembly.GetType("StartupBridge_Hotfix"); //var method = type.GetMethod("Start", BindingFlags.Public | BindingFlags.Static); //method.Invoke(null, new object[] { false }); } }
private static void GenAdapterFile(Type t, string dir) { string fileHeader = @" using System; using System.Collections; using System.Collections.Generic; using ILRuntime.CLR.Method; using ILRuntime.Runtime.Enviorment; using ILRuntime.Runtime.Intepreter; "; string className = t.Name.Replace("`", "_"); string fullName = t.FullName.Replace("`", "_");; string publicNameStr = "public class " + className + "Adapter:CrossBindingAdaptor\r\n" + "{\r\n"; string BaseCLRTypeStr = "public override Type BaseCLRType\r\n" + "{\r\n" + " get\r\n" + " {\r\n" + " return typeof(" + fullName + ");//这是你想继承的那个类\r\n" + " }\r\n" + "}\r\n" + "public override Type AdaptorType\r\n" + "{\r\n" + " get\r\n" + " {\r\n" + " return typeof(Adaptor);//这是实际的适配器类\r\n" + " }\r\n" + "}\r\n" + "public override object CreateCLRInstance(ILRuntime.Runtime.Enviorment.AppDomain appdomain, ILTypeInstance instance)\r\n" + "{\r\n" + " return new Adaptor(appdomain, instance);//创建一个新的实例\r\n" + "}\r\n" + "//实际的适配器类需要继承你想继承的那个类,并且实现CrossBindingAdaptorType接口\r\n" + "public class Adaptor : " + fullName + ", CrossBindingAdaptorType\r\n" + "{\r\n" + " ILTypeInstance instance;\r\n" + " ILRuntime.Runtime.Enviorment.AppDomain appdomain;\r\n" + " //缓存这个数组来避免调用时的GC Alloc\r\n" + " object[] param1 = new object[1];\r\n" + " public Adaptor()\r\n" + " {\r\n" + "\r\n" + " }\r\n" + " public Adaptor(ILRuntime.Runtime.Enviorment.AppDomain appdomain, ILTypeInstance instance)\r\n" + " {\r\n" + " this.appdomain = appdomain;\r\n" + " this.instance = instance;\r\n" + " }\r\n" + " public ILTypeInstance ILInstance { get { return instance; } }\r\n"; //反射virtual的函数 List <MethodInfo> methods = t.GetMethods().ToList().FindAll((_method) => { return(_method.IsPublic && _method.IsVirtual && _method.DeclaringType == t); }); string methodsStr = ""; foreach (var md in methods) { methodsStr += CreateOverrideMethod(md) + "\r\n"; } string outputString = fileHeader + "\r\n" + publicNameStr + BaseCLRTypeStr + methodsStr + "}\r\n}"; FileStream file = null; StreamWriter sw = null; //有什么错误,就直接让系统去抛吧。 //file = new FileStream( IPath.Combine(dir , className+ "Adapter.cs"), FileMode.Create); file = new FileStream(FileTool.CombinePaths(dir, className + "Adapter.cs"), FileMode.Create); sw = new StreamWriter(file); sw.Write(outputString); sw.Flush(); sw.Close(); file.Close(); }
public void CopyAB2SABtn() { BuildABScript.CopyAssetBundlesTo(FileTool.CombinePaths(Application.streamingAssetsPath, LWUtility.AssetBundles)); AssetDatabase.Refresh(); }