From 05a6ee672ca88e4103bdbf594545744968178f06 Mon Sep 17 00:00:00 2001 From: liuwei Date: Thu, 20 Mar 2025 10:21:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E5=9D=97=E7=AE=A1=E7=90=86=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/plugin_manager/main.py | 115 +++++++++++++++++++++++---------- 1 file changed, 81 insertions(+), 34 deletions(-) diff --git a/plugins/plugin_manager/main.py b/plugins/plugin_manager/main.py index d8c1a64..180c93e 100644 --- a/plugins/plugin_manager/main.py +++ b/plugins/plugin_manager/main.py @@ -320,32 +320,55 @@ class PluginManagerPlugin(MessagePluginInterface): # 记录插件状态,以便重新加载后恢复 was_running = plugin.status == PluginStatus.RUNNING - # 先卸载插件 - 使用模块名而不是显示名称 - self.LOG.info(f"正在卸载插件 {actual_plugin_name}(模块名:{module_name}) 以进行重载") - if not self.plugin_manager.unload_plugin(module_name): - wcf.send_text(f"❌插件 {actual_plugin_name} 卸载失败,无法重载", - (roomid if roomid else sender), sender) - return False, f"插件 {actual_plugin_name} 卸载失败,无法重载" - - # 然后加载插件 - 使用模块名而不是显示名称 - self.LOG.info(f"正在加载插件 {module_name}") - plugin = self.plugin_manager.load_plugin(module_name) - if not plugin: - wcf.send_text(f"❌插件 {actual_plugin_name} 加载失败", - (roomid if roomid else sender), sender) - return False, f"插件 {actual_plugin_name} 加载失败" - - # 如果之前是启用状态,则重新启用 - if was_running: - self.LOG.info(f"正在启用插件 {actual_plugin_name}") - if not self.plugin_manager.start_plugin(module_name): # 使用模块名而不是显示名称 - wcf.send_text(f"⚠️插件 {actual_plugin_name} 重载成功,但启用失败", + try: + # 先确保插件已停止运行 + if was_running: + self.LOG.info(f"插件 {actual_plugin_name} 正在运行,先停止它") + self.plugin_manager.stop_plugin(module_name) + + # 先卸载插件 - 使用模块名而不是显示名称 + self.LOG.info(f"正在卸载插件 {actual_plugin_name}(模块名:{module_name}) 以进行重载") + + # 尝试卸载,如果失败则尝试强制从注册表移除 + unload_success = self.plugin_manager.unload_plugin(module_name) + if not unload_success: + self.LOG.warning(f"常规卸载失败,尝试强制卸载插件 {actual_plugin_name}") + # 从插件注册表中移除 + if actual_plugin_name in self.plugin_registry.get_all_plugins(): + self.plugin_registry.remove_plugin(actual_plugin_name) + unload_success = True + + if not unload_success: + wcf.send_text(f"❌插件 {actual_plugin_name} 卸载失败,无法重载", (roomid if roomid else sender), sender) - return True, f"插件 {actual_plugin_name} 重载成功,但启用失败" - - wcf.send_text(f"✅插件 {actual_plugin_name} 重载成功", - (roomid if roomid else sender), sender) - return True, f"插件 {actual_plugin_name} 重载成功" + return False, f"插件 {actual_plugin_name} 卸载失败,无法重载" + + # 然后加载插件 - 使用模块名而不是显示名称 + self.LOG.info(f"正在加载插件 {module_name}") + plugin = self.plugin_manager.load_plugin(module_name) + if not plugin: + wcf.send_text(f"❌插件 {actual_plugin_name} 加载失败", + (roomid if roomid else sender), sender) + return False, f"插件 {actual_plugin_name} 加载失败" + + # 如果之前是启用状态,则重新启用 + if was_running: + self.LOG.info(f"正在启用插件 {actual_plugin_name}") + if not self.plugin_manager.start_plugin(module_name): # 使用模块名而不是显示名称 + wcf.send_text(f"⚠️插件 {actual_plugin_name} 重载成功,但启用失败", + (roomid if roomid else sender), sender) + return True, f"插件 {actual_plugin_name} 重载成功,但启用失败" + + wcf.send_text(f"✅插件 {actual_plugin_name} 重载成功", + (roomid if roomid else sender), sender) + return True, f"插件 {actual_plugin_name} 重载成功" + except Exception as e: + import traceback + error_trace = traceback.format_exc() + self.LOG.error(f"重载插件 {actual_plugin_name} 时出错: {e}\n{error_trace}") + wcf.send_text(f"❌重载插件出错: {str(e)}", + (roomid if roomid else sender), sender) + return False, f"重载插件出错: {e}" def _unload_plugin(self, plugin_name: str, wcf, sender: str, roomid: str, silent: bool = False) -> Tuple[bool, str]: """卸载插件""" @@ -375,19 +398,43 @@ class PluginManagerPlugin(MessagePluginInterface): # 获取插件的模块名,这才是插件管理器需要的名称 module_name = plugin.__class__.__module__.split('.')[-2] + # 先确保插件已停止运行 + if plugin.status == PluginStatus.RUNNING: + self.LOG.info(f"插件 {actual_plugin_name} 正在运行,先停止它") + self.plugin_manager.stop_plugin(module_name) + # 使用插件管理器卸载插件 - 使用模块名而不是显示名称 self.LOG.info(f"正在卸载插件 {actual_plugin_name}(模块名:{module_name})") - success = self.plugin_manager.unload_plugin(module_name) - if success: + + # 尝试直接从插件注册表中移除插件 + try: + # 先尝试正常卸载 + success = self.plugin_manager.unload_plugin(module_name) + + # 如果失败,尝试强制从注册表移除 + if not success: + self.LOG.warning(f"常规卸载失败,尝试强制卸载插件 {actual_plugin_name}") + # 从插件注册表中移除 + if actual_plugin_name in self.plugin_registry.get_all_plugins(): + self.plugin_registry.remove_plugin(actual_plugin_name) + success = True + + if success: + if not silent: + wcf.send_text(f"✅插件 {actual_plugin_name} 卸载成功", + (roomid if roomid else sender), sender) + return True, f"插件 {actual_plugin_name} 卸载成功" + else: + if not silent: + wcf.send_text(f"❌插件 {actual_plugin_name} 卸载失败", + (roomid if roomid else sender), sender) + return False, f"插件 {actual_plugin_name} 卸载失败" + except Exception as e: + self.LOG.error(f"卸载插件 {actual_plugin_name} 时出错: {e}") if not silent: - wcf.send_text(f"✅插件 {actual_plugin_name} 卸载成功", + wcf.send_text(f"❌卸载插件出错: {str(e)}", (roomid if roomid else sender), sender) - return True, f"插件 {actual_plugin_name} 卸载成功" - else: - if not silent: - wcf.send_text(f"❌插件 {actual_plugin_name} 卸载失败", - (roomid if roomid else sender), sender) - return False, f"插件 {actual_plugin_name} 卸载失败" + return False, f"卸载插件出错: {e}" def _load_plugin(self, plugin_name: str, wcf, sender: str, roomid: str, silent: bool = False) -> Tuple[bool, str]: """加载插件"""