jumplist不记录访问频次和时间,真实访问数据需解析%appdata%\microsoft\windows\recent下的.lnk文件,结合file.getlastaccesstimeutc()(需确认fsutil启用)及shelllinkhelper解析目标路径。

JumpList 本身不保存“常用文件和程序访问记录”
Windows 的 JumpList 不是日志系统,它不会自动记录用户打开过什么、开了几次、什么时候开的。你看到的“最近”或“常用”项,其实是 Shell 自己根据 Recent Items(NTUSER.DAT 中的 USN 日志 + 缓存)和应用程序主动提交的 JumpList 条目混合生成的——而后者完全由应用自己控制,且默认只存“快捷方式”,不带时间戳或频次。
所以,直接从 JumpList XML 或注册表里解析不出“用户最常打开的 Excel 文件”这类数据。
想获取真实访问频率,得绕到 Windows Shell 的 Recent Items
真正反映用户近期行为的是 %APPDATA%\Microsoft\Windows\Recent 目录下的 .lnk 文件,每个链接都包含原始路径、访问时间(通过 File.GetLastAccessTimeUtc() 可读),部分还嵌入了目标 PIDL 和访问计数(需解析 shell link 二进制结构)。
-
File.GetLastAccessTimeUtc()在 NTFS 上默认关闭,很多系统返回的是创建/修改时间,不是真实访问时间 —— 要先确认是否启用:fsutil behavior query disablelastaccess返回 0 才有效 - 不能只看 .lnk 文件名,要解析其内部目标路径:用
ShellLinkHelper(需 P/InvokeIShellLinkW)或第三方库如ManagedShell - 部分 .lnk 指向已删除路径,
GetTargetPath()会失败,必须加 try/catch
C# 解析 JumpList XML 文件只能拿到“静态快照”
如果你的应用曾调用 Jumplist.AddToRecent() 或写入过 CustomCategory,这些数据会以 XML 形式缓存在 %APPDATA%\Microsoft\Windows\Recent\AutomaticDestinations 或 CustomDestinations 下(文件名是 GUID)。但这些 XML 不含访问时间、次数,只有 ID、AppID、相对路径。
示例片段(实际是二进制格式,XML 是反编译后近似):
<destination appid="notepad.exe"> <item path="%USERPROFILE%\Documents\readme.txt" /> </destination>
- 路径是相对的或经过 ShellItemID 编码的,不能直接
File.Exists() - 不同 Windows 版本存放位置和加密方式不同(Win10/11 用 AES 加密,需调用
IKnownFolderManager获取正确路径) - 没有权限读取其他用户的
AutomaticDestinations,即使你是管理员,也受 UAC 和 VirtualStore 隔离
更可行的替代方案:用 Windows Timeline API(仅 Win10 1809+)
如果目标系统较新,Windows.System.UserActivity 和 ActivityFeed 是唯一提供频次、时间、上下文的官方接口。但它需要用户开启“活动历史记录”,且只对声明了 activity capability 的 UWP/MSIX 应用开放。
- 桌面应用(.NET Framework/.NET Core)无法直接调用,需通过
CoreApplication.CreateNewView()启动一个隐藏 UWP 进程桥接 - 用户可随时在“设置 > 隐私 > 活动历史记录”中关闭,此时所有数据为空
- 返回的
UserActivity对象里有LastModifiedTime和ActiveDuration,但没有“打开次数”字段 —— 需自己按天/按文件聚合
真正难的不是读数据,而是把零散的 Recent Items、JumpList 提交、Timeline 活动拼成一条可信的行为链。比如同一个文件可能出现在三个地方,时间相差几小时,哪个算“真实访问”?这没有标准答案,得看你具体要做什么。










