- 桌面应用
【免费下载链接】WechatExporter
Wechat Chat History Exporter 微信聊天记录导出备份程序
导读
WechatExporter 是一个用 C++ 重写的跨平台微信聊天记录导出与备份工具,它直接读取 iTunes/iOS 备份中的微信数据,将聊天记录解析后导出为 Text、HTML、PDF 三种格式,并支持异步加载、消息过滤、增量导出与页面模板定制。本文以项目 README.md 为主线,结合仓库源码(WechatExporter/core/、WechatExporter/res/templates/等)深入讲解其使用步骤、导出选项、增量导出原理与模板定制方法,读完你可以独立完成一次从手机备份到聊天记录归档的全流程操作,并理解其底层实现机制。
项目定位:C++ 重写的跨平台聊天记录导出工具
微信 PC 端在 Windows 3.7.6 内测版、macOS 3.5.5 Beta 版中上线了聊天记录迁移功能,可以将 Mac 端与手机端的聊天记录互相迁移、合并浏览,也可将手机端聊天记录备份至 PC 端以缩减微信体积。WechatExporter 正是面向这一场景的开源方案:它参考了 stomakun/WechatExport-iOS(外部参考项目)的设计思路,改用 C++ 实现,以在各平台以更少依赖运行,同时增加了聊天群名称的解析支持和更多消息类型的导出支持,导出格式支持 Text、HTML、PDF 三种。
从仓库目录结构看,项目包含三大工程部分:
WechatExporter/:macOS/iOS 工程(Xcode,含ViewController.mm、AppDelegate.mm等 UI 层代码);vcproject/:Windows 工程(Visual Studio,含WechatExporter.sln、WechatExporter.vcxproj、MainFrm.h等 MFC/WTL 界面代码);WechatExporter/core/:与平台无关的核心逻辑,包括备份解析(ITunesParser.h)、微信数据解析(WechatParser.h)、消息解析(MessageParser.h)、导出调度(Exporter.h)、增量导出上下文(ExportContext.h)以及 PDF 转换接口(PdfConverter.h)等。
这种"核心逻辑与平台 UI 分离"的结构,正是该工具能够同时覆盖 Windows 与 macOS 的基础。
核心功能特性一览
根据 README.md 的说明,WechatExporter 的核心能力包括:
- 三种消息加载方式:导出的聊天记录页面可以设置为「打开时一次性加载完成」(默认方式)、「打开时异步加载」、「页面滑动到底部时加载更多」,可在菜单"选项"中修改;
- 页面过滤功能:可以在导出的页面增加过滤功能(按关键词搜索、按消息类型筛选),同样在菜单"选项"中设置;
- PDF 导出:实质是先导出"打开时一次性加载完成"的 HTML 页面,再通过 Google Chrome 或 Microsoft Edge 浏览器转换成 PDF 文件,转换耗时较长,过程中不要关闭自动弹出的命令行窗口;
- 增量导出:在菜单"选项"中设置增量导出后,仅导出上一次导出最后一条消息之后的部分;再次备份后微信中的聊天记录可以删除,下一次导出可以把同一个聊天群的后续消息合并到一起。
这些选项在源码层面与 Exporter.h 中的设置接口一一对应:
void setTextMode(bool textMode = true); void setPdfMode(bool pdfMode = true); void setOrder(bool asc = true); // 消息时间倒序导出 void saveFilesInSessionFolder(bool flags = true); // 头像/表情文件存入聊天记录子目录 void setSyncLoading(bool syncLoading = true); // 一次性加载 void setLoadingDataOnScroll(bool loadingDataOnScroll = true); // 滚动加载 void setIncrementalExporting(bool incrementalExporting); // 增量导出 void supportsFilter(bool supportsFilter = true); // 页面过滤 void useRemoteEmoji(bool useEmojiUrl); // 使用远端表情 URL而 MessageParser.h 中定义的SessionParsingOption位标志(SPO_TEXT_MODE、SPO_PDF_MODE、SPO_DESC、SPO_ICON_IN_SESSION、SPO_SYNC_LOADING、SPO_SUPPORT_FILTER、SPO_INCREMENTAL_EXP等)则揭示了这些选项在消息解析阶段的底层影响——例如SPO_ICON_IN_SESSION表示把头像和表情文件存放到聊天记录子目录,SPO_USING_REMOTE_EMOJI对应远端表情,SPO_TEXT_MODE(0xFFFF)代表纯文本导出模式。
操作步骤:从 iTunes 备份到聊天记录归档
第一步:通过 iTunes 备份手机
- 通过 iTunes 将手机备份到电脑上,备份时不要选择设置口令(加密备份无法直接解析,ITunesParser.h 中的
BackupManifest结构体也显式记录了m_encrypted加密标志); - Windows 系统下备份一般位于目录:
C:\用户\<用户名>\AppData\Roaming\Apple Computer\MobileSync\Backup\; - Android 手机用户可以找一个 iPad/iPhone 设备,先用微信的"聊天记录迁移"功能把聊天记录迁移到 iPad/iPhone 上,然后通过 iTunes 备份到电脑。
第二步到第四步:下载、运行、按界面操作
- 从项目的发布(Releases)页面下载最新版本的执行文件(最新版本下载见 README 顶部;Windows 提供 x64 版本,macOS 提供 x64 版本);
- 执行解压出来的
WechatExport.exe/WechatExporter.app。Windows 下如果运行报缺少必需的 DLL 文件,请安装 Visual C++ 2017 Redistributable 后再尝试运行(下载地址见 README"系统依赖"一节); - 按界面提示进行操作:选择 iTunes 备份目录与导出目录、勾选要导出的聊天会话、配置导出选项后点击"导出"。
下面是 Windows 与 macOS 两个平台的实际程序界面:
从 macOS 截图可以看到界面提供的典型导出选项:备份目录选择、导出目录选择、「按消息时间倒序导出」「头像和表情文件存放到聊天记录子目录」「仅导出文本」「HTML 数据异步加载」等复选框,底部还显示当前关联的 iTunes、iOS、微信版本信息,对应 Exporter.h 中的getITunesVersion()、getIOSVersion()、getWechatVersion()接口。
第五步:查看导出结果
导出完成后的页面为浏览器可打开的 HTML 文件,页面样式与消息气泡布局由模板目录控制(详见下文"模版修改"小节)。
消息类型覆盖:不止文本和图片
WechatExporter 在原始参考项目的基础上扩展了更多消息类型的解析。以 MessageParser.h 中定义的常量为例,顶层消息类型(MSGTYPE_*)包括:
| 常量 | 值 | 含义 |
|---|---|---|
MSGTYPE_TEXT | 1 | 文本消息 |
MSGTYPE_IMAGE | 3 | 图片消息 |
MSGTYPE_VOICE | 34 | 语音消息 |
MSGTYPE_SHARECARD | 42 | 名片分享 |
MSGTYPE_VIDEO | 43 | 视频消息 |
MSGTYPE_EMOTICON | 47 | 表情 |
MSGTYPE_LOCATION | 48 | 位置消息 |
MSGTYPE_APP | 49 | 应用/小程序消息(App 消息) |
MSGTYPE_SYS | 10000 | 系统消息 |
MSGTYPE_RECALLED | 10002 | 撤回消息 |
MSGTYPE_APP(49)之下还细分了APPMSGTYPE_*子类型:文本(1)、图片(2)、语音(3)、视频(4)、链接(5)、附件(6)、表情(15)、转发消息(19)、视频号卡片(50)、视频号动态(51)、聊天记录引用(57)、转账(2000)、红包(2001)等;转发消息内部又区分FWDMSG_DATATYPE_*:文本、图片、视频、链接、位置、附件、名片、嵌套转发(17)、小程序(19)、视频号(22)等。MessageParser中相应的parseText、parseImage、parseVoice、parseVideo、parseAppMsg*、parseFwdMsg*系列方法(见 MessageParser.h)即为各类型消息到 HTML 模板值(TemplateValues)的转换实现。
导出页面加载模式与过滤功能的底层实现
三种加载方式如何工作
导出的 HTML 页面加载逻辑集中在 frame.html 的脚本中。页面通过asyncLoadingType变量区分加载策略:
- 一次性加载(默认):HTML 中直接内联全部消息内容;
- 打开时异步加载(
asyncLoadingType == "initial"):页面加载完成后通过loadMsgsForNextPage()动态请求消息分页数据; - 滚动到底部加载更多(
asyncLoadingType == "onscroll"):监听页面滚动事件,接近底部时(pageOffset > containerDivOffset - 20)触发loadMsgsForNextPage()。
异步模式下,消息被拆分成msg-N.js分页文件(%%DATA_PATH%%/msg-+ pageNumber +.js,见 frame.html),每页消息数量由%%SIZE_OF_PAGE%%占位符控制(默认 100),总消息数与总页数由%%NUMBER_OF_MSGS%%、%%NUMBER_OF_PAGES%%注入。
页面过滤功能
过滤功能由 filter.html 提供:页面顶部生成关键词输入框(回车触发searchElements,匹配span.dspname发送者昵称与span.msg-text消息文本)以及「照片」「视频」「所有」三个快捷筛选按钮(分别调用showImageMsgs、showVideoMsgs、showAllMsgs,最终通过filterMsg按msgType属性筛选div.msg元素)。过滤时若可见消息数不足一页,还会自动继续加载下一页消息,保证筛选结果完整。
历史 Bug 提醒(1.8.0.7 及以前版本)
README 特别标注了一个历史问题:1.8.0.7 以前版本的异步加载方式存在较严重的 Bug——设置为"滚动到页面底部异步加载"时,越靠后的页码加载的消息数量越少;设置为"打开全部消息异步加载"时,消息只能加载到一半。处理方式:
- 如果 iTunes 备份还存在,请使用 1.8.0.8 及以上版本重新导出;
- 如果过往备份已清除,可下载 1.8.0.8 的补丁程序(Win64 / macOS 64 位两个版本),解压后把
wxexpatch.exe(Windows)/wxexppatch(macOS)拷贝到导出目录并执行,即可修复已导出的页面,补丁修复的文件清单可查看日志文件patch.log。
如果你仍在使用旧版本导出的页面,这一点需要特别留意。
增量导出原理:按会话记录消息游标
增量导出是"备份后删除微信聊天记录、再次导出合并"这一工作流的基石。其实现集中在 ExportContext.h:
- 核心数据结构是
m_maxIdForSessions:以聊天会话用户名(usrName)为键、记录该会话已导出的最大消息 ID(int64_t maxId); - 导出时通过
getMaxId(usrName, maxId)读取游标,导出完成后通过setMaxId(usrName, maxId)更新游标; - 整个上下文通过
serialize()序列化为 JSON(字段含options、exportTime、sessions数组,其中每项为{usrName, maxId}),下次导出时通过unserialize()反序列化恢复游标;Exporter.h 的hasPreviousExporting(outputDir, options, exportTime)用于检测输出目录中是否存在上次导出记录。
对应地,SessionParser.h 中buildMsgEnumerator(session, minId)支持从指定最小 ID 开始枚举消息,正是增量导出"只导出游标之后的消息"的取数入口。因此增量导出的完整链路是:上次导出的maxId→ 本次按minId过滤 → 仅导出新增消息 → 更新游标并写回导出上下文。
PDF 导出的实质与注意事项
PDF 模式并非直接生成 PDF 文件。README 明确说明:PDF 格式实质是导出"打开时一次性加载完成"的 HTML 页面,然后通过 Google Chrome 或者 Microsoft Edge 浏览器的打印功能转成 PDF 文件。因此:
- PDF 模式下页面必须一次性加载完成(不能使用异步加载模式,否则内容不完整);
- 转 PDF 文件耗时较长,请不要关闭自动弹出的命令行窗口;
- 平台层通过 PdfConverter.h 定义抽象接口(
makeUserDirectory、convert(htmlPath, pdfPath)),由各平台实现(macOS 见WechatExporter/PdfConverterImpl.h,Windows 见vcproject/PdfConverterImpl.h)。
模版修改:自定义导出页面样式
解压目录下的res\templates(macOS 版本位于Contents\Resources\res)子目录存放了输出聊天记录的 HTML 页面模板,模板支持通过%%变量%%形式的占位符注入数据。README 强调:通过两个%包含起来的字符串(如%%NAME%%)不要修改,除此之外的页面内容和格式都可以自行调整。
仓库中WechatExporter/res/templates/下提供了完整的模板集,例如:
- listitem.html:会话列表项模板,使用
%%ITEMPICPATH%%(头像路径)、%%ITEMLINK%%(链接)、%%ITEMTEXT%%(显示文本)三个占位符; - msg.html:普通文本消息气泡模板,使用
%%ALIGNMENT%%(左/右对齐)、%%MSGID%%、%%MSGTYPE%%、%%AVATAR%%、%%NAME%%、%%TIME%%、%%MESSAGE%%等占位符; - audio.html:语音消息模板,通过
%%AUDIOPATH%%注入音频文件路径,渲染<audio controls>播放器; - frame.html:整页骨架(样式、头部、异步加载与过滤脚本),
%%DISPLAYNAME%%、%%USRNAME%%、%%SESSION_USRNAME%%、%%BODY%%、%%HEADER_FILTER%%等占位符; - filter.html:过滤栏片段(关键词搜索框与照片/视频/所有按钮);
- 其余还有
image.html、video.html、card.html、share.html、refermsg.html、channels.html、emoji.html、notice.html、system.html、plainshare.html等按消息类型划分的模板; res/templates_txt/目录下则是对应的纯文本导出模板(Text 格式导出使用)。
要定制导出样式,只需修改这些 HTML 模板中的布局、CSS 或增加辅助脚本,重新导出即可生效;注意保留所有%%XXX%%占位符及其语义。README 特别感谢了 Chao.M 帮忙优化当前的模板。
系统依赖与运行环境
README 明确的系统要求如下:
- Windows 版本:Windows 7 及以上(不支持 XP),需要安装 Visual C++ 2017 Redistributable(官方最新支持的 Visual C++ 下载页面见 README"系统依赖"一节);
- MacOS 版本:macOS 10.10(Yosemite)及以上。
程序编译:第三方依赖与平台差异
WechatExporter 依赖以下第三方库(完整清单见 README.md「程序编译」一节):
| 库 | 用途/说明 | 平台 |
|---|---|---|
| libxml2 | XML 解析(聊天消息 XML 内容解析,对应XmlParser) | 通用 |
| libcurl | 网络请求(远程表情、头像下载等) | 通用 |
| libsqlite3 | SQLite 数据库读取(微信MM.sqlite、message_*.sqlite) | 通用 |
| libprotobuf | Protobuf 解析(微信部分数据格式) | 通用 |
| libjsoncpp | JSON 解析/序列化(如导出上下文的读写) | 通用 |
| lame | MP3 编码(语音转码,见Utils_audio.cpp、Utils_silk.cpp) | 通用 |
| silk | 微信 SILK 语音解码 | 通用 |
| libplist | Apple plist 解析(备份 Manifest) | 通用 |
| libiconv | 字符编码转换 | 仅 Windows |
| openssl | 加密/摘要 | 仅 Windows |
| WTL | Windows UI 框架 | 仅 Windows |
编译注意事项(来自 README):
- MacOS 下:
libxml2、libcurl、libsqlite3直接使用 Xcode 自带的库,其它第三方库需自行编译;libmp3lame需手动删除文件include/libmp3lame.sym中的lame_init_old行; - Windows 下:
silk自带 Visual Studio 工程文件,可以直接利用 Visual Studio 编译;其余除了libplist之外,都通过 vcpkg 编译;libplist在 vcpkg 中也存在,但在编译x64-windows-statictarget 时报了错,因此直接通过 Visual Studio 建立工程进行编译。
如需获取源码自行编译,可使用git clone https://gitcode.com/gh_mirrors/we/WechatExporter克隆仓库。
备份数据在备份包中的位置(源码级补充)
了解数据在哪,有助于排查导出异常。从 WechatParser.h 中的过滤器可以还原微信数据在 iTunes 备份中的典型路径结构:
- UserFolderFilter:匹配
Documents/<32位哈希>/DB/MM.sqlite,即每个微信账号的数据库目录(32 位哈希为用户目录标识); - MessageDbFilter:在用户目录下匹配
DB/message_<1~4位数字>.sqlite,即分片消息数据库; MMSettingInMMappedKVFilter匹配Documents/MMappedKV/mmsetting.archive.<uid>.crc,对应通过 MMKVReader.h 读取的 MMKV 键值存储(用于解析用户名、昵称、头像等);SessionCellDataFilter匹配celldataV7之类的会话列表缓存文件;- 备份文件索引本身(Manifest、
ITunesFile结构体)见 ITunesParser.h,isDir()通过flags == 2判断目录项。
这也是 README 强调"备份时不要设置口令"的原因——加密备份会破坏这些原始文件的直接可读性。
已测试的 iTunes 与微信版本组合
README 末尾列出了开发者在实际环境中的兼容性验证记录,可作为选择备份/微信版本的参考:
| 操作系统 | iTunes 版本 | 微信版本 | iOS 版本 |
|---|---|---|---|
| Windows | 12.3.3.17 | 6.5.9 | — |
| Windows | 12.5.1.21 | 6.3.30 | — |
| Windows | 12.10.10.2 | 7.0.2 | — |
| Windows | 12.10.9.3 | 7.0.15 | — |
| Windows | 12.9.5.5 | 7.0.2 | — |
| Windows 10 | 12.11.0.26(Microsoft Store) | 7.0.2 / 8.0.1 | — |
| macOS Catalina(Embedded iTunes) | — | 8.0.1 / 8.0.2 | — |
| Windows 7 | 12.10.9.3 | 8.0.2 | — |
| Windows 10 | 12.11.3.17 | 8.0.7 | — |
| Windows 7 / macOS Catalina | 12.10.9.3(Embedded iTunes) | 7.0.2 | iOS 9.3.5 |
| Windows | 12.10.3.1 | 7.0.10 | iOS 13.3 |
| macOS 11.6(Embedded iTunes) | — | 8.0.9 | iOS 15.0 |
| macOS 11.6(Embedded iTunes) | — | 8.0.18 | iOS 15.4 |
注意:以上为项目仓库中记录的实测组合,不代表对所有版本的承诺;实际使用时以「iTunes 未加密备份 + 对应微信版本」为基本前提。
小结
WechatExporter 的完整工作流可以概括为:iTunes 未加密备份 → 解析备份中的微信数据库(MM.sqlite / message_*.sqlite / MMKV)→ 按会话枚举并解析各类消息 → 套用 HTML 模板(或纯文本模板)生成导出页面 → 可选异步分页/过滤/增量合并 → 可选经 Chrome/Edge 转为 PDF。对普通用户,掌握 README 中的五步操作即可完成备份与导出;对开发者,core/目录下的解析器与模板机制则提供了清晰的可扩展路径——新增消息类型、定制页面样式、接入其他备份格式都可以从对应模块入手。
- 桌面应用
【免费下载链接】WechatExporter
Wechat Chat History Exporter 微信聊天记录导出备份程序
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考