网友作品 #000217 · 提交于 2026/09/08
Outlook 归档压缩加载项:附件瘦身、PST切分与模糊搜索




1 / 4
作品简介
OutlookMailArchive 是一个 Outlook 邮件归档压缩 COM 加载项,解决迁移后的两大痛点:一是几万封邮件、大附件导致磁盘空间紧张;二是 Outlook 内置搜索基于 Windows Search、只支持前缀匹配,无法像 Foxmail 那样输入编号片段就模糊命中(如输入 104058 找到标题含 ADR104058 的邮件)。
插件以「归档压缩」功能区组的形式集成在 Outlook 的发送/接收选项卡中,提供归档压缩设置、立即归档压缩、文件夹压缩、压缩选中邮件等入口;另在开始选项卡提供「模糊搜索」窗体。归档设置窗体可配置邮箱账号与批处理范围、按月/季度/年自由切分的 PST 规则、图片/PDF/Office 压缩参数,并支持监听新邮件自动压缩归档。
核心亮点
- 附件原地压缩:图片(JPEG/PNG/BMP/TIFF/WebP/HEIC 等)、PDF、Office 文档(docx/xlsx/pptx 重打包压缩内嵌图片)三类附件统一压缩,替换后保留内嵌图片的 MAPI 属性,正文图片显示不受影响
- 按阈值压缩不越压越大:图片/Office 默认 256KB、PDF 默认 512KB 阈值触发,压缩结果不小于原件时放弃替换,效果以邮件 Size 前后差值验证
- 时间段切分 PST:按接收时间命中规则迁入模板命名的 PST(支持年份、日期占位符),镜像保留源文件夹层级,PST 自动挂载并改显示名,未命中规则的邮件原地不动
- Foxmail 式模糊搜索:全账号邮件元数据内存索引,多关键词 AND 子串匹配,毫秒级响应,结果可排序、可二次筛选,双击直接打开原邮件;索引通过本地持久化、事件增量、定时重扫三通道保持更新
- 批处理与自动处理并行:对收件箱/已发送/归档文件夹(含子文件夹)批量执行,新邮件自动处理始终监听所选账号收件箱,互不影响
- 部署零依赖:.NET Framework 4.6.2 目标框架,PowerShell 脚本写注册表安装(HKCU/HKLM),配套构建、卸载、诊断与冒烟测试脚本
- COM 资源纪律:Interop 对象严格释放,防止 Outlook 进程句柄泄漏
技术与工具
- 形态:COM 加载项(非 VSTO),实现 IDTExtensibility2 与 IRibbonExtensibility,Ribbon XML 采用 Fluent UI customUI 嵌入式资源分发
- 技术栈:.NET Framework 4.6.2 + WPF/WinForms 互操作(ElementHost 宿主,解决 DPI 缩放与键盘消息)+ HandyControl 主题控件
- 压缩组件:Magick.NET(图片)、PDFsharp(PDF 页面图片重采样)、System.IO.Compression(OOXML 文档)
- 互操作与日志:Microsoft.Office.Interop.Outlook 15.0、NLog 滚动日志
- 开发方式:AI 编程类工具 + 国内顶级 AI 模型,复用作者此前项目的邮件压缩技术
开发过程
作者此前尝试用 RPA 方式把邮件从 FastMail/Foxmail 迁到 Outlook,后来发现服务器保存了所有邮件、直接用 Outlook 收取即可,方案大幅简化。邮件压缩技术(图片、Office 文档、PDF 压缩)可复用之前项目的积累。落地过程仍有曲折,性能与逻辑等细节前后花了约两天时间优化完成。
适用场景
- 从 Foxmail 迁移到 Outlook 的用户:保留编号片段模糊搜邮件的习惯
- 企业/个人邮箱归档瘦身:几万封邮件、大附件占满磁盘时批量压缩并按年切分 PST
- 需要控制单 PST 体积(建议 20GB 左右、上限 50GB)的长期归档管理
- 新邮件自动压缩归档,保持收件箱长期轻量
原始提交内容(点开查看,可复制全文去问 AI)
OutlookMailArchive 项目说明
Outlook 邮件归档压缩 COM 加载项(经典 Outlook 桌面版)
1. 项目概述
本项目是一个面向经典 Outlook 桌面版的 COM 加载项,服务于从 Foxmail 迁移到 Outlook 的使用场景,解决迁移后的两大痛点:
- 磁盘空间紧张:邮件数量几万封、附件体积大。通过附件原地压缩(图片/PDF/Office 文档)+ 按时间段切分 PST 归档,控制单文件体积、释放空间占用。
- 搜索体验差:Outlook 内置搜索基于 Windows Search 索引,只支持前缀匹配,无法像 Foxmail 那样按编号片段模糊命中(例如输入
104058找到标题含ADR104058的邮件)。本插件内置自研内存索引,提供毫秒级子串模糊搜索。
2. 功能总览
| 功能 | 入口 | 说明 |
|---|---|---|
| 归档压缩设置 | 发送/接收 归档压缩 归档压缩设置 | 配置目标账号、时间段归档规则、PST 命名模板、压缩参数;可从设置窗体直接发起批处理 |
| 立即归档压缩 | 发送/接收 归档压缩 立即归档压缩 | 跳过设置窗体,按已保存配置对勾选范围(收件箱/已发送/归档文件夹,含子文件夹)执行批处理 |
| 新邮件自动处理 | 设置项开关 | 监听新到达邮件,自动按规则压缩附件并归档到对应年份 PST |
| 文件夹压缩 | 发送/接收 归档压缩 文件夹压缩 | 选择任意文件夹(含搜索文件夹)原地压缩全部邮件附件,不迁移邮件 |
| 压缩选中邮件 | 发送/接收 归档压缩 压缩选中邮件 | 对邮件列表中选中的一封或多封邮件原地压缩,快速验证压缩效果 |
| 模糊搜索 | 开始 模糊搜索(新建组之前) | 全账号邮件元数据内存索引,多关键词 AND 子串匹配,结果可排序、可二次筛选,双击打开原邮件 |
3. 技术架构
3.1 加载项形态
-
COM 加载项(非 VSTO):入口类
Connect实现IDTExtensibility2(生命周期)与IRibbonExtensibility(Ribbon 定制),以 ProgIdOutlookMailArchive.AddIn注册。 -
Ribbon XML:采用 Fluent UI customUI(2009/07 schema),以嵌入式资源
Resources/Ribbon.xml分发,按钮图标 PNG 同为嵌入式资源,由RibbonController通过getImage回调动态提供。 -
注册方式:PowerShell 安装脚本写注册表(默认 HKCU 当前用户;管理员账号自动补写 HKLM 机器级),无安装器依赖。
3.2 技术栈
| 类别 | 选型 | 用途 |
|---|---|---|
| 目标框架 | .NET Framework 4.6.2 | 兼容 Win10 1607+ 自带运行时,部署零依赖 |
| UI 框架 | WPF + WinForms 互操作 | WPF 视图宿主在 WinForms 窗体(FormBlankForWpf + ElementHost),解决无 Outlook 内嵌 WPF 窗口场景下的 DPI 缩放与键盘消息问题 |
| UI 组件库 | HandyControl 3.5.1 | 主题化控件(DataGrid、Growl 提示等);HandyControlRuntime 负责在 Outlook 进程内合并主题资源字典并支持强调色预设 |
| 图片压缩 | Magick.NET-Q8-AnyCPU 14.14.0 | JPEG/PNG/BMP/TIFF/WebP/HEIC 等格式缩放与重编码 |
| PDF 压缩 | PDFsharp 6.2.4 | 解析 PDF 页面对象,重采样其中图片流 |
| Office 文档压缩 | System.IO.Compression | OOXML(docx/xlsx/pptx)本质是 ZIP,重打包并压缩内部媒体图片 |
| Outlook 互操作 | Microsoft.Office.Interop.Outlook 15.0 | 邮件/文件夹/Store 对象模型操作 |
| 日志 | NLog 6.1.3 | 滚动日志文件,AddInLog 封装 |
3.3 架构分层
Connect(COM 入口/生命周期)
RibbonController Ribbon 命令分发 + 图标
AddInRuntime 基础设施:Application 引用、配置加载、目录、装配解析
InboxWatcher 新邮件自动处理(NewMailEx 主 + ItemAdd 兜底双事件源)
MailIndexService 模糊搜索元数据索引(单例,后台采集/持久化/增量更新)
Views(WPF 视图层)
ArchiveSettingsView 设置窗体
ArchiveProgressView 批处理进度窗体
FolderPickerView 文件夹树选择(含搜索文件夹分组)
FolderCompressView 文件夹压缩进度窗体
SmartSearchView 模糊搜索窗体
Services(业务服务层)
ArchiveSettings 配置模型(XmlSerializer 持久化 settings.xml)
ArchiveBatchService 批处理编排:范围扫描 规则匹配 压缩 迁移
ArchiveStoreService 规则 PST 定位/挂载/镜像文件夹结构 + 显示名管理
MailCompressionService 单封邮件附件替换(保留内嵌图片 MAPI 属性)
AttachmentCompressionService 纯字节压缩引擎(图片/PDF/Office 三类)
FolderCompressService 文件夹原地压缩(含 Size 前后对比验证)
SmartSearchService 搜索执行:内存索引命中或现场遍历回退
3.4 关键设计点
附件压缩正确性
-
内嵌正文图片的
PR_ATTACH_CONTENT_ID、PR_ATTACHMENT_HIDDEN、PR_ATTACH_MIME_TAG等 MAPI 属性在替换附件后逐一恢复,避免正文图片显示失败。 -
压缩效果以
MailItem.Size保存前后差值验证(真实落盘字节数),而非仅附件字节数。 -
压缩按阈值触发(图片/Office 默认 256KB、PDF 默认 512KB),避免小文件“越压越大”;结果不大于原件时放弃替换。
规则 PST 归档
-
按接收时间命中时间段规则
[开始日期, 结束日期],迁入按模板命名的 PST(支持{0}开始年份、{1}结束年份、{2}/{3}起止日期占位符)。 -
源文件夹结构镜像保留到目标 PST(如
收件箱\客户APST 内同名层级)。 -
PST 需要时自动挂载(
AddStoreEx+ 轮询等待),挂载后把默认显示名(“Outlook 数据文件”)改为文件名,便于辨识;用户手动改过的名称不覆盖。 -
未命中任何规则的邮件留在原文件夹不动。
模糊搜索索引(三通道更新)
| 通道 | 覆盖场景 | 时效 |
|---|---|---|
| 本地持久化加载 | Outlook 重启后秒级就绪(%LOCALAPPDATA%\outlook-com-addin-builder\OutlookMailArchive\mail_index.dat) |
启动即搜 |
| 事件增量 | 收件箱 + 已发送的 ItemAdd/ItemChange;运行中新挂载 PST 的 StoreAdd 触发该 Store 全量扫描 | 即时 |
| 定时重扫兜底 | 每 10 分钟按 LastModificationTime 降序增量扫描,无变化文件夹读 1 行即停 | 10 分钟 |
-
增量水位线按数据文件(Store)分组记录,避免新挂载旧 PST 被全局水位线跳过;扫描带 2 小时重叠窗口,EntryID 幂等覆盖去重。
-
索引条目仅存托管值(EntryID/StoreID/标题/发件人/收件人/时间/文件夹路径/修改时间),不持有 COM 对象。
-
命中未挂载 PST 的邮件时引导选择文件、
AddStoreEx挂载并校验 StoreID 后打开。 -
删除邮件产生的脏条目由“打开失败自动清理”兜底,另提供手动重建索引。
COM 资源纪律
- 所有 Interop 对象严格
Marshal.ReleaseComObject释放,遍历 Stores/Folders 的代码统一 keep/release 模式,防止 Outlook 进程句柄泄漏。
4. 目录结构
OutlookMailArchive/
src/OutlookMailArchive/ 源码(SDK 风格 csproj)
Connect.cs COM 入口
RibbonController.cs Ribbon 回调
AddInRuntime.cs / AddInLog.cs 基础设施
HandyControlRuntime.cs WPF 主题宿主
Automation/ 冒烟测试 Automation 对象
Services/ 业务服务(见 3.3)
Views/ WPF 视图 + WinForms 宿主
Resources/ Ribbon.xml + 图标
scripts/ 构建/安装/卸载/诊断/冒烟 PowerShell 脚本
runtime/office-com/ Extensibility/Office 互操作程序集
dist/ 交付目录(files + scripts + 安装说明)
docs/ 图标源文件与蓝图文档
logs/ 本地开发日志
5. 构建与部署
- 构建:
scripts\build_addin.ps1(dotnet build -c Release,产物复制到dist\files\)。 - 安装:关闭 Outlook 后双击
dist\install_addin.bat(底层install_addin.ps1,写 HKCU 注册;管理员账号补写 HKLM)。 - 卸载:
dist\uninstall_addin.bat。 - 诊断:
dist\diagnose_addin.bat检查程序集、CodeBase、注册表与 .NET 运行时。 - 验收:源码目录
scripts\test_outlook_smoke.ps1冒烟脚本(通过 COMAddIn.Object Automation 入口验证),不随 dist 交付。
6. 运行时数据位置
| 数据 | 路径 |
|---|---|
| 配置 settings.xml | %LOCALAPPDATA%\outlook-com-addin-builder\OutlookMailArchive\ |
| 搜索索引 mail_index.dat | 同上 |
| 附件压缩工作目录 | 同上 work\(用后清理) |
| 运行日志 | 安装目录 logs\ |
| 年份 PST | 设置中指定的归档目录(默认取 Outlook 默认数据文件所在目录) |
7. 已知限制与注意事项
-
PST/OST 数据文件大小在删除/压缩邮件后不会立即缩小,需在 Outlook 中执行“压缩数据文件”才回收磁盘空间。
-
单个 PST 建议控制在 20GB 左右(索引与访问性能最佳区间),上限 50GB;本插件按时间段切分 PST 的设计即为控制单文件体积。
-
模糊搜索索引不采集附件内容(只索引邮件元数据),Windows Search 若另行启用仍会索引正文,其索引位于 C 盘且与 PST 体积正相关——本插件的搜索不依赖 Windows Search。
-
新邮件自动处理始终只监听所选账号的收件箱;批处理与自动处理互不影响。