Exemplo n.º 1
0
 /// <summary>
 /// 插件全部卸载
 /// </summary>
 public void UnLoad()
 {
     Loading = true;
     LogHelper.WriteLog("开始卸载插件...");
     CallFunction(FunctionEnums.Functions.Exit);
     CallFunction(FunctionEnums.Functions.Disable);
     NotifyIconHelper.ClearAppMenu();
     foreach (var item in AppDomainSave)
     {
         var c = Plugins.Find(x => x.iLib == item.Key);
         UnLoad(c);
         AppDomain.Unload(item.Value);
     }
     Plugins.Clear();
     AppDomainSave.Clear();
     GC.Collect();
     Loading = false;
     LogHelper.WriteLog("插件卸载完毕");
 }
Exemplo n.º 2
0
        /// <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);
        }