public void Load() { string path = @"data\plugins"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } DirectoryInfo directoryInfo = new DirectoryInfo(path); int count = 0; foreach (var item in directoryInfo.GetFiles().Where(x => x.Extension == ".dll")) { if (!File.Exists(item.FullName.Replace(".dll", ".json"))) { LogHelper.WriteLine(CQLogLevel.Error, "插件载入", $"插件 {item.Name} 加载失败,原因:缺少json文件"); continue; } JsonLoadSettings loadsetting = new JsonLoadSettings { CommentHandling = CommentHandling.Ignore }; JObject json = JObject.Parse(File.ReadAllText(item.FullName.Replace(".dll", ".json")), loadsetting); int authcode = new Random().Next(); Dll dll = new Dll(); IntPtr iLib = dll.Load(item.FullName, json); if (iLib == (IntPtr)0) { LogHelper.WriteLine(CQLogLevel.Error, "插件载入", $"插件 {item.Name} 加载失败,返回句柄为空,GetLastError={Dll.GetLastError()}"); continue; } dll.DoInitialize(authcode); KeyValuePair <int, string> appInfotext = dll.GetAppInfo(); AppInfo appInfo = new AppInfo(appInfotext.Value, 0, appInfotext.Key , json["name"].ToString(), json["version"].ToString(), Convert.ToInt32(json["version_id"].ToString()) , json["author"].ToString(), json["description"].ToString(), authcode); Plugins.Add(new Plugin(iLib, appInfo, json, dll)); LogHelper.WriteLine(CQLogLevel.InfoSuccess, "插件载入", $"插件 {appInfo.Name} 加载成功"); cq_start(Marshal.StringToHGlobalAnsi(item.FullName), authcode); NotifyIconHelper.Init(json); count++; } LogHelper.WriteLine(CQLogLevel.Info, "插件载入", $"一共加载了{count}个插件"); }
/// <summary> /// 以绝对路径路径载入拥有同名json的dll插件 /// </summary> /// <param name="filepath">插件dll的绝对路径</param> /// <returns>载入是否成功</returns> public bool Load(string filepath) { FileInfo plugininfo = new FileInfo(filepath); if (!File.Exists(plugininfo.FullName.Replace(".dll", ".json"))) { LogHelper.WriteLog(LogLevel.Error, "插件载入", $"插件 {plugininfo.Name} 加载失败,原因:缺少json文件"); return(false); } JObject json = JObject.Parse(File.ReadAllText(plugininfo.FullName.Replace(".dll", ".json"))); int authcode = new Random().Next(); Dll dll = new Dll(); if (!Directory.Exists(@"data\tmp")) { Directory.CreateDirectory(@"data\tmp"); } //复制需要载入的插件至临时文件夹,可直接覆盖原dll便于插件重载 string destpath = @"data\tmp\" + plugininfo.Name; File.Copy(plugininfo.FullName, destpath, true); //复制它的json File.Copy(plugininfo.FullName.Replace(".dll", ".json"), destpath.Replace(".dll", ".json"), true); IntPtr iLib = dll.Load(destpath, json);//将dll插件LoadLibrary,并进行函数委托的实例化; AppDomainSetup ads = new AppDomainSetup { ApplicationBase = AppDomain.CurrentDomain.BaseDirectory, DisallowBindingRedirects = false, DisallowCodeDownload = true, ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile }; AppDomain newappDomain = AppDomain.CreateDomain(iLib.ToString(), null, ads); AppDomainSave.Add(iLib, newappDomain); Proxy.Init(iLib, json); if (iLib == (IntPtr)0) { LogHelper.WriteLog(LogLevel.Error, "插件载入", $"插件 {plugininfo.Name} 加载失败,返回句柄为空,GetLastError={Dll.GetLastError()}"); } //执行插件的init,分配一个authcode dll.DoInitialize(authcode); //获取插件的appinfo,返回示例 9,me.cqp.luohuaming.Sign,分别为ApiVer以及AppID KeyValuePair <int, string> appInfotext = dll.GetAppInfo(); AppInfo appInfo = new AppInfo(appInfotext.Value, 0, appInfotext.Key , json["name"].ToString(), json["version"].ToString(), Convert.ToInt32(json["version_id"].ToString()) , json["author"].ToString(), json["description"].ToString(), authcode); bool enabled = GetPluginState(appInfo);//获取插件启用状态 //保存至插件列表 Plugin plugin = (Plugin)newappDomain.CreateInstanceAndUnwrap(typeof(Plugin).Assembly.FullName , typeof(Plugin).FullName , false , BindingFlags.CreateInstance , null , new object[] { iLib, appInfo, json.ToString(), dll, enabled, appInfotext.Value } , null, null); Plugins.Add(plugin); LogHelper.WriteLog(LogLevel.InfoSuccess, "插件载入", $"插件 {appInfo.Name} 加载成功"); cq_start(Marshal.StringToHGlobalAnsi(destpath), authcode); //将它的窗口写入托盘右键菜单 NotifyIconHelper.LoadMenu(json); return(true); }