diff --git a/astrbot/core/message/components.py b/astrbot/core/message/components.py index a9bb091224..15265c38d1 100644 --- a/astrbot/core/message/components.py +++ b/astrbot/core/message/components.py @@ -720,13 +720,38 @@ async def get_file(self, allow_return_url: bool = False) -> str: if allow_return_url and self.url: return self.url - if self.file_ and os.path.exists(self.file_): - return os.path.abspath(self.file_) + if self.file_: + path = self.file_ + if path.startswith("file://"): + # 处理 file:// (2 slashes) 或 file:/// (3 slashes) + # pathlib.as_uri() 通常生成 file:/// + path = path[7:] + # 兼容 Windows: file:///C:/path -> /C:/path -> C:/path + if ( + os.name == "nt" + and len(path) > 2 + and path[0] == "/" + and path[2] == ":" + ): + path = path[1:] + + if os.path.exists(path): + return os.path.abspath(path) if self.url: await self._download_file() if self.file_: - return os.path.abspath(self.file_) + path = self.file_ + if path.startswith("file://"): + path = path[7:] + if ( + os.name == "nt" + and len(path) > 2 + and path[0] == "/" + and path[2] == ":" + ): + path = path[1:] + return os.path.abspath(path) return "" diff --git a/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py b/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py index 99ea727315..7e42a0fd86 100644 --- a/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py +++ b/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py @@ -45,6 +45,19 @@ async def _from_segment_to_dict(segment: BaseMessageComponent) -> dict: if isinstance(segment, File): # For File segments, we need to handle the file differently d = await segment.to_dict() + file_val = d.get("data", {}).get("file", "") + if file_val: + import pathlib + + try: + # 使用 pathlib 处理路径,能更好地处理 Windows/Linux 差异 + path_obj = pathlib.Path(file_val) + # 如果是绝对路径且不包含协议头 (://),则转换为标准的 file: URI + if path_obj.is_absolute() and "://" not in file_val: + d["data"]["file"] = path_obj.as_uri() + except Exception: + # 如果不是合法路径(例如已经是特定的特殊字符串),则跳过转换 + pass return d if isinstance(segment, Video): d = await segment.to_dict()