jumplist文件是windows复合文档格式,需用com接口istorage/istream解析,不能直接用fstream读取;其路径在%appdata%\microsoft\windows\recent\automaticdestinations下,含destlist和streamxxxxxx等流,须处理unicode路径与shitemid结构,并注意权限、uac及系统版本差异。

JumpList文件是二进制结构,不能用fstream直接读文本
Windows JumpList(自动跳转列表)保存在 %APPDATA%\Microsoft\Windows\Recent\AutomaticDestinations 目录下,文件名是 32 字符的 GUID(如 1d49ab5a7836c04ea0b27823911e414d.automaticDestinations-ms),后缀带 .automaticDestinations-ms。这些不是普通文本或 JSON,而是基于 Windows Structured Storage(复合文档格式,类似旧版 .doc)封装的二进制文件,内部含多个流(DestList、Stream00000001 等)。直接用 std::ifstream 读取只会得到乱码或空内容。
必须用 COM 接口 IStream + IStorage 解析复合文档
C++ 原生标准库不支持解析这种格式,需调用 Windows API 的 COM 接口:IStorage 打开复合文件,再用 IStream 读取指定流。关键步骤如下:
- 调用
StgOpenStorage打开文件路径(注意传入STGM_READ | STGM_SHARE_DENY_WRITE) - 用
IStorage::OpenStream获取"DestList"流(该流含跳转项元数据,如最后访问时间、项数、版本号) -
DestList是二进制结构:前 4 字节为版本(通常0x00000002),接着是 16 字节 GUID(列表 ID),再后是 8 字节整数(项总数) - 实际跳转项(如最近打开的 Excel 文件路径)存在
StreamXXXXXX(如Stream00000001)中,需遍历所有以Stream开头的流并解析其 shell item 格式(SHITEMID链表)
注意:StreamXXXXXX 中的数据是 Unicode 路径 + shell 属性,不是纯字符串,需用 ILLoadFromStream 或手动解析 SHITEMID 结构,否则会截断或乱码。
权限和 UAC 限制常导致 OpenStorage 失败
常见错误是 StgOpenStorage 返回 STG_E_ACCESSDENIED 或 0x80030005。这不是代码写错,而是因为:
- JumpList 文件被资源管理器或 Shell 占用(尤其用户正在使用“最近项目”时)
- 程序未以相同完整性级别运行(例如以管理员身份运行但 JumpList 属于标准用户)
- 路径中含重定向(如
%APPDATA%指向Roaming,但某些应用写到Local\Microsoft\Windows\Recent)
实操建议:先用 GetEnvironmentVariable(L"APPDATA", ...) 拼出完整路径;尝试加 STGM_PRIORITY 标志;失败时改用 CopyFile 先复制一份临时文件再打开;避免在 Explorer 进程活跃时读取。
没有跨平台方案,且 Win10/Win11 解析逻辑有差异
JumpList 格式未公开,微软也未提供 C++ SDK 封装。社区逆向结果(如 libfwsi)仅支持 Python/C,C++ 项目需自行对接。更麻烦的是:
- Win10 v1809+ 引入了新的
CustomDestinations子目录,部分跳转项可能分散存储 - Win11 对
DestList版本号升级(出现0x00000003),旧解析器会跳过后续流 - 某些企业环境禁用 JumpList(组策略关闭“开始菜单中的最近项目”),此时目录可能为空
真正能稳定提取路径的,几乎都依赖 IShellItemArray + SHGetDestinationList(仅限当前用户 JumpList,且需 Windows 10 1703+),但这不是读文件,而是调 Shell API 构造实时列表 —— 和你问的“读取 .automaticDestinations-ms 文件”本质不同。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











