Category: system

  • “连不上”不一定是“被墙”:Xray 升级后,旧客户端内核握不上 REALITY

    “连不上”不一定是“被墙”:Xray 升级后,旧客户端内核握不上 REALITY

    一个长期稳定的自建 VLESS + REALITY 节点,某天开始客户端全线 timeout。第一反应通常是“这个 IP 被 GFW 封了”——于是换网络、加中继、甚至准备换 IP。但在我们这次的排查里,IP 并没有被封:真正的变化发生在服务端——Xray 被升级到了新版本,而手上的旧客户端内核(Clash 用的 mihomo)已经握不上它的 REALITY 了。

    这篇文章只讲我们实际验证过的事实:怎么把“被墙”和“客户端不兼容”分开,我们试过哪些办法、结果如何,以及——同样重要——哪些我们并没有证实

    症状

    • 原本稳定的节点,突然开始大面积超时。
    • 换网络、换设备、换运营商,现象都差不多。
    • TCP 端口不一定完全不通,但客户端就是连不上。
    • 直觉上很像“IP 被盯上了”。

    第一步:别急着判定“被墙”

    关键的一点:“卡在 TLS / REALITY 握手”这个现象,被墙和协议不兼容都会产生,单看它分不出来。

    还有两个常见误区要避开:

    • 普通 TLS 工具的失败不能当证据。对 REALITY 入站,curl / openssl s_client 本来就完不成握手(REALITY 会拒绝非授权握手),它们报错是正常的。
    • 要看内核自己的日志——xray / mihomo / sing-box 的连接日志,而不是外部工具的输出。

    既然现象分不出来,就得做对照实验,把变量一个个拿掉。

    决定性证据:在服务端本机走回环,换内核对照

    这是整次排查里最有说服力的一步,也是我们真正确证的事实。

    做法:在服务器本机,用不同的客户端内核、同样的参数,去连本机的 127.0.0.1 入站。这条路径不出公网、不经过任何跨境链路,等于把“网络封锁”这个变量直接拿掉,只剩下“客户端内核”这一个变量。

    同一台机、同一时刻、同一个 127.0.0.1:443,结果是:

    客户端内核(回环连本机入站) 结果
    xray-core(与服务端同源、同版本) ✅ 握手成功
    mihomo(与客户端同版本) ❌ 握手失败

    结论很直接:这是“客户端内核 ↔ 服务端 Xray”的兼容性问题,跟 IP、跟网络封锁无关——因为这条路径根本没碰网络。回头一查,服务端的 Xray 确实在不久前被升级到了一个很新的大版本;而我们手上的旧客户端内核(至少本次测试的 mihomo / sing-box)跟不上它的 REALITY 了。

    这也把“是不是被墙”摘了出去:回环这条路根本不出网络,等于把“封锁”这个变量排除在外。在我们这台机器上 IP 也确实没被封,于是问题就锁定在内核兼容性上。

    我们在客户端侧试过的办法,都没把它救回来

    很多人的第一反应是“升级一下客户端就好”。我们试了,对 mihomo / sing-box 不管用。以下都在服务端回环 / 链路上实测过:

    尝试 结果
    xray-core(直连 / 回环) ✅ 成功(唯一能过的)
    mihomo 最新 stable + 最新 Alpha ❌ 失败
    mihomo,7 种 uTLS 指纹逐个试 ❌ 全失败
    mihomo,显式打开 support-x25519mlkem768 开关 ❌ 仍失败
    sing-box(较新 uTLS 的版本) ❌ 失败

    在我们这组测试里,唯一能稳定握上手的就是 xray-core,而且是在直连 / 回环下。所以实用的结论是:如果你直连节点、用的又是 Clash / mihomo,单纯升版本(包括打开那个常被怀疑的后量子开关)在我们这里没救回来——换一个 xray-core 内核的客户端,是我们这里唯一验证有效的办法。

    如果你是经中继(proxy chain)连节点:客户端这条路走不通

    有一类很常见的用法:节点是一个固定的境外出口,永远从一个墙外的前置跳板接进去,也就是 本地 → 前置跳板 → 境外出口 这条 proxy chain。

    先说清楚:REALITY 本身并不是“不能被中继”——Xray 的 dialerProxy 本就支持链式拨号,把 REALITY 套在前置代理后面是常见用法。但在我们这台升级后的服务器上,我们试过的组合都没能让 REALITY 经中继跑通

    • xray-core 的 REALITY 经前置跳板转发到服务端——握手没成功(试过的两条中继表现还不一样:一条直接 EOF,一条到达服务端鉴权阶段后被判无效连接)。
    • 同一条中继转发普通 TLS 到同一端口却能通——说明中继能到达服务端、也扛得住 TLS——至少能把问题收窄到“这版 REALITY 经该中继转发”这一段(确切卡点我们没独立证实,见下文)。
    • 我们把客户端这边能试的组合(不同内核单独及混用、不同指纹、那个后量子开关)都试了,没有一个能让 REALITY 经中继接通

    所以在“必须走中继”的场景里,客户端这条路我们没能走通。对症的做法是从服务端入手:把出口那一跳换成一个能被正常中继的协议(纯 TCP、两端内核都支持就行)。换掉之后,经前置跳板接入即可恢复。

    顺带排除一个坑:在我们试过的 TCP 类中继上,Hysteria2 这类 UDP 协议也不合适。它是 UDP/QUIC,经 TCP 类中继要做 UDP-over-TCP 封装,而我们试的商业中继并不还原这种封装,照样超时。UDP 系协议(Hy2 / TUIC)更适合直连,要这样经 TCP 类中继转发往往不顺。

    我们没有证实的部分(同样要讲清楚)

    为了不把推测当结论,下面这些我们并没有坐实:

    • 没有证实“元凶就是后量子”。社区里常见一种归因:把这一轮“Xray 升级后旧客户端连不上”算到新版默认带上的后量子能力头上(如 X25519MLKEM768 密钥交换、以及可选的 ML-DSA-65 认证)。这与我们看到的现象不矛盾、也是重点怀疑对象;但我们这台服务器的入站当时其实没有显式的后量子字段,而且把客户端的 support-x25519mlkem768 打开也没用。所以我们能下的最稳结论只到——“新版 Xray 的 REALITY 与旧客户端内核不兼容”,至于具体卡在哪个特性,没有独立验证。
    • 没有证实 REALITY 经中继失败的确切机理。一个合理的猜测是:REALITY 的鉴权信息嵌在 ClientHello 里、对 TCP 分帧敏感,经中继重新分段后被破坏了——但这只是推断,我们也没排除中继自身实现的影响。

    结论:一套可复制的判断流程

    1. “卡在握手”既不能证明是 GFW、也不能证明不是——别靠现象拍脑袋。
    2. 服务端本机走 127.0.0.1 回环、换不同客户端内核对照:如果结果按内核分成败,就能确认存在协议兼容性问题,且这一部分换 IP、加中继都解决不了(这条路径不碰网络,封锁与否被排除在外)。
    3. 如果只有 xray-core 能连,多半是服务端 Xray 升级后、旧客户端内核没跟上。直连场景 → 换 xray-core 内核的客户端;走中继场景 → 从服务端把出口换成能被中继的协议。

    一句话:这类故障也许不是“IP 被墙”,而是“服务端升级了、客户端没跟上”。在下结论、急着换 IP 之前,先用回环对照把“协议不兼容”这条单独验掉。

    参考资料

    1. XTLS / Xray-core, PR #4915 “REALITY protocol: Add optional Post-Quantum ML-DSA-65 verification”(后量子认证的来源)
      https://github.com/XTLS/Xray-core/pull/4915
    2. XTLS / Xray-core, transport/internet/reality/reality.gomain 分支会漂移,复核时建议钉到具体 release tag)
      https://github.com/XTLS/Xray-core/blob/main/transport/internet/reality/reality.go
    3. MetaCubeX / mihomo v1.19.9 release(加入 support-x25519mlkem768
      https://github.com/MetaCubeX/mihomo/releases/tag/v1.19.9
    4. sing-box documentation, “TLS Shared Fields”
      https://sing-box.sagernet.org/configuration/shared/tls/
    5. NIST FIPS 203, “Module-Lattice-Based Key-Encapsulation Mechanism Standard”
      https://csrc.nist.gov/pubs/fips/203/final
    6. NIST FIPS 204, “Module-Lattice-Based Digital Signature Standard”
      https://csrc.nist.gov/pubs/fips/204/final

    致谢与署名

    本文的排查与初稿由 Claude Code 完成:复现“全线 timeout”、区分“TCP 连通性”与“握手失败”、在服务端走 127.0.0.1 回环用不同客户端内核做对照实验,把病根定位到「新版 Xray REALITY 与旧客户端内核不兼容」,并实测发现这版 REALITY 经我们试过的中继转发都跑不通(同一条中继转发普通 TLS 却能过)。

    站点维护者(本博客作者)做了几处关键决断与一手事实纠正——尤其是坚持“这个 IP 其实没被封”的判断(正是它把方向从“绕中继对抗封锁”拉回到“换协议 / 对齐版本解决兼容性”),并在 Windows / iOS 上做了实测验证。

    技术准确性、逻辑严谨度与引用规范的审校由 codex(OpenAI Codex) 完成:对论断逐条复核(包括把若干超出证据的措辞收紧),并校准了术语与参考文献。

  • 一个甩不掉的红叉:深挖 Dropbox 文件夹图标上的”幽灵”同步错误

    一个甩不掉的红叉:深挖 Dropbox 文件夹图标上的”幽灵”同步错误

    一次完整的取证式排查记录:从”重启大法”一路打到 Dropbox 的内部 SQLite 数据库,推翻三个看似正确的结论,最后用一条官方排障命令收尾。

    症状

    Windows 11 的文件资源管理器左侧导航栏里,Dropbox 文件夹图标上挂着一个红圈白叉(Dropbox 的”同步错误 / 无法同步”徽标)。但诡异的是:

    • 右下角系统托盘里的 Dropbox 图标完全正常;
    • Dropbox 自带面板底部明确写着 “✓ Your files are up to date”(文件均为最新);
    • 这个红叉已经持续很多天,期间重启过电脑很多次,纹丝不动。

    一句话:Dropbox 自己说一切正常,但文件夹图标却在报错。 到底谁在撒谎?

    一个关键观察(也是整场排查的起点):同一个 Dropbox 文件夹,在两个不同的资源管理器窗口里,一个有红叉、一个没有。同一对象在不同窗口显示不一致,直觉上指向”缓存 / 刷新问题”而非”实时真实状态”。后面会看到,这个直觉对了一半,又错了一半。


    背景知识:文件夹图标上的”徽标”是怎么来的

    Windows 资源管理器允许第三方通过 Shell Icon Overlay Handler(外壳覆盖图标处理器) 在文件/文件夹图标上叠加一个小角标。Dropbox、OneDrive、Google Drive、TortoiseGit/SVN、各种网盘都靠它来画”已同步 / 同步中 / 出错”的小图标。

    但这里有一个臭名昭著的坑:Windows 最多只认 15 个覆盖图标处理器。

    一个容易混淆的点:这台机器上其实有两套图标系统并存。 Dropbox 开了 Files On-Demand(基于 Windows 的 Cloud Files / 云文件 API),文件级的”绿勾(已同步)/ 白云(仅在线)”是 Cloud Files 的 hydration 状态图标画的,不受这 15 个槽位限制;而文件夹级的”同步中 / 出错”角标(至少在本机这套环境里)走的仍是上面这套老式 Shell 覆盖图标处理器(DropboxExt)。本文要追的那个红叉属于后者,所以下文只沿覆盖图标处理器这条线走。

    这个限制来自底层 image list 最多只能有 15 个 overlay mask,从 Windows XP 时代硬编码至今,Raymond Chen 在《The Old New Thing》里专门解释过它的来龙去脉(devblogs.microsoft.com)。注册表位置在:

    HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers
    HKLM\SOFTWARE\WOW6432Node\...\ShellIconOverlayIdentifiers

    普遍观察到的行为是:Windows 按键名的字母序枚举、只保留前 15 个,后面的静默丢弃。(15 这个上限有 Raymond Chen 的文章背书;而”按键名排序加载”更多是业界长期观察到的实现行为,并非官方逐字承诺的契约——下文我会用实测而非这条规则来下判断。)于是各家应用为了抢进前 15,纷纷在自己的键名前面加前导空格(空格的 ASCII 比字母小,排序靠前)——这是一场公开的”军备竞赛”,ownCloud 的开发者甚至专门提了 issue 吐槽(owncloud/client #3141),也有不少博客教你手动加空格给自己常用的应用提权(garethjmsaunders.co.ukitwriting.com)。

    记住这个机制,因为它马上要把我带进第一个(错误的)结论。


    第一回合:当成图标缓存花屏 —— 失败

    最常见的”图标错乱”原因是 Windows 的图标缓存损坏。标准疗法是重启资源管理器、重建图标缓存数据库:

    # 重启 explorer
    Stop-Process -Name explorer -Force; Start-Process explorer
    
    # 彻底重建图标缓存
    Stop-Process -Name explorer -Force
    Remove-Item "$env:LOCALAPPDATA\IconCache.db" -Force
    Remove-Item "$env:LOCALAPPDATA\Microsoft\Windows\Explorer\iconcache_*.db" -Force
    Start-Process explorer

    删掉了 16 个 iconcache_*.db,重启。红叉纹丝不动。

    结论:它不是 Windows 图标缓存花屏。 一个能扛过图标缓存彻底重建的角标,要么是实时画上去的,要么藏在别处。


    第二回合:15 个覆盖图标名额被吃满 —— 看似铁证,其实站不住

    我把 ShellIconOverlayIdentifiers 下的所有处理器列出来并按加载顺序排序,再逐个解析到它们背后的 DLL:

    槽位 键名 归属
    1–7 OneDrive17 微软 OneDrive(FileSyncShell64.dll)
    8–14 .WorkspaceExt06 百度网盘(YunShellExtV164.dll,用”前导空格 + 点”伪装,抢占最高优先级)
    15 AccExtIco1 Adobe CoreSync
    16–27 DropboxExt0110 ❌ Dropbox,全部排在 15 名之外

    OneDrive 占 7 个 + 百度网盘占 7 个 + Adobe 占 1 个,正好吃满 15 个名额,Dropbox 的 10 个处理器一个都没排上。看起来完美解释了一切:Dropbox 画不出正确徽标,旧红叉也清不掉。

    实际把注册表项按键名排序后的样子(为抢前 15,各家都在键名前堆前导空格 / 加点号):

    [排进]  1.'       OneDrive1'  … 7.'       OneDrive7'        (FileSyncShell64.dll)
    [排进]  8.'      .WorkspaceExt0' …14.'      .WorkspaceExt6'  (百度网盘 YunShellExtV164.dll)
    [排进] 15.'   AccExtIco1'                                    (Adobe CoreSync)
    [出局] 16.'   DropboxExt01' …25.'   DropboxExt10'           (Dropbox ← 全部落在 15 名之外)
    [出局] 26.'  115ErrorOverlayIcon' …                         (115 网盘)

    这正是网上铺天盖地的那个解释——”装太多网盘把 Dropbox 挤掉了”(itwriting.comCentreStackWikipedia: List of shell icon overlay identifiers)。

    但我没有就此收手。 因为有个细节对不上:如果 Dropbox 的处理器没被加载,它连红叉都画不出来才对。于是我去查 explorer.exe 当前到底加载了哪些 DLL:

    Get-Process explorer | ForEach-Object { $_.Modules } |
      Where-Object { $_.FileName -match 'DropboxExt|FileSyncShell|YunShellExt|CoreSync' } |
      Select-Object -Expand FileName -Unique

    实测输出(只列命中的模块):

    Dropbox  : 已加载 -> C:\Program Files (x86)\Dropbox\Client\DropboxExt64.95.0.dll
    OneDrive : 已加载 -> C:\Program Files\Microsoft OneDrive\...\FileSyncShell64.dll
    Baidu    : 未加载
    Adobe    : 已加载 -> C:\Program Files (x86)\Common Files\Adobe\...\CoreSync_x64.dll

    结果与”名额被吃满”的预期正好相反:

    • DropboxExt64.95.0.dll —— ✅ 已加载、活动中
    • 百度网盘 YunShellExtV164.dll —— ❌ 没加载(因为百度网盘进程当时没运行!)

    反转: 百度网盘虽然霸占着注册表里的高优先级槽位,但它没运行,所以它的处理器根本没被加载(也就谈不上占用 overlay 槽)。”15 名额被吃满”这个流传最广的解释,在这台机器上根本不成立

    教训一:注册表里”占着名额”不等于”运行时真加载了”。至少在这台机器上,排在 16 名之外的 DropboxExt 照样被加载进了 explorer 并在画角标——”名额被吃满”的解释在此不成立。(严格说,单凭”DLL 已加载”还不足以断言 Windows 的 15 计数规则,也不能证明别的 handler”让出了名额”;但第四回合会证明红叉确实是 Dropbox 实时画的,从而坐实它的覆盖处理器在正常工作。)要快速验证,直接看 explorer.exe 的已加载模块即可。

    既然 DropboxExt 是活的,那红叉就是 Dropbox 自己实时画的。问题升级为:Dropbox 为什么坚持认为根目录有错?

    本回合小结 —— 观察到:DropboxExt 已加载、红叉仍在;排除了:”被挤出 15 名额导致画不出图标”这个解释(在本机);还不能证明:Dropbox 的”错误”判断到底源于真实同步问题,还是陈旧状态。


    第三回合:desktop.ini 红鲱鱼

    文件夹图标可以被自身的 desktop.ini 静态指定。如果 Dropbox 在出错时往 desktop.ini 写了个”错误版”图标资源、修好后没改回来,那就能完美解释”持久且扛重启”。一查:

    [.ShellClassInfo]
    IconResource=C:\Program Files (x86)\Dropbox\Client\Dropbox.exe,-13001

    确实指定了自定义图标 -13001。我用 PrivateExtractIcons(负数索引按资源 ID 提取)把它抠出来看:

    # PrivateExtractIcons 传负的 nIconIndex 时,按资源 ID 的绝对值提取
    [IconRes]::Save("...\Dropbox.exe", 13001, "res_13001.png", 256)

    -13001 是一个干净的蓝色 Dropbox 文件夹图标,没有任何红叉。所以 desktop.ini 是清白的,文件夹的基础图标正常,红叉确实是叠加在上面的动态覆盖,不是静态图标。

    教训二:desktop.iniIconResource=...,-N 里的 N资源 ID(负号表示”这是 ID,不是序号”),Windows 的图标提取语义里负值通常被解释为资源 ID(而非从 0 起的序号)——这一点在 ExtractIconEx/SHDefExtractIcon 的官方文档里有明确说明。我用 PrivateExtractIcons 传负值做了验证性提取,取到的正是资源 ID 13001 对应的图标。


    第四回合:注册表命名空间节点 + 一个幽灵副本

    导航栏里的 Dropbox 项不是普通的”固定文件夹”,而是一个 命名空间外壳扩展(shell namespace extension),跟 OneDrive 一样,通过 HKCU\Software\Classes\CLSID\{GUID} + ...\Desktop\NameSpace\{GUID} 注册。一查,发现注册了两个都叫 “Dropbox”、都指向 C:\Users\sudos\Dropbox 的 CLSID:

    • {9E639962-...} —— 当前生效(在 Desktop\NameSpace 里)
    • {E31EA727-...} —— 幽灵副本(不在 NameSpace 里,疑似重装/迁移残留)

    为了判断红叉是”卡在这个外壳节点上”还是”Dropbox 实时喂的”,我做了一个删除—恢复对照实验(全程只改 HKCU、先 reg export 备份、可逆):

    1. 删掉幽灵副本 {E31EA727} + 把活动项 {9E639962} 连定义带挂载点整个删除;
    2. 重启 explorer → 侧边栏 Dropbox 项连同红叉一起消失;
    3. 从备份原样导回活动项;
    4. 重启 explorer → 红叉在节点一出现的瞬间又回来了。

    这一步是决定性的:红叉不在注册表 / 外壳缓存里。 删除节点只是把”显示红叉的载体”拿掉了;载体一回来,Dropbox 立刻又把红叉喂上去。

    教训三:想区分”显示层缓存卡死”还是”数据源实时输出”,做一次”删除载体—恢复载体”对照实验最干脆。


    第五回合:翻 Dropbox 自己的数据库

    既然是 Dropbox 实时输出”错误”,那它的依据在哪?我开始只读地翻 Dropbox 的本地状态(都不碰云端、不触发下载):

    ...\Dropbox\instance1\icon.db(81 MB) —— 名字很像”图标状态库”,但一看 schema 就排除了:键名是 tpng<路径>_256、值是 Python pickle,这其实是缩略图预览缓存,与徽标无关。

    sync_history.db —— 近期 99 条事件全是正常的 file/add|edit|delete · upload|download,零错误、零冲突,最近一次同步就在当天下午。

    sync_and_storage.db(127 MB) —— 只有一张 storage_files 表(Files-On-Demand 占位索引),根本没有”状态 / 错误”字段

    到这里,Dropbox 所有可读的本地证据都在说”我很健康”。


    第六回合:”仅在线”状态反推出真相

    storage_files425,472 条记录,本地实际 406,481 个文件,其中 406,076 个是”仅在线”(online-only)占位符

    “仅在线 vs 本地有内容”是靠 Windows Cloud Files 给占位符打的文件属性位数出来的(只读元数据,不触发下载):

    # RECALL_ON_OPEN(0x40000) / RECALL_ON_DATA_ACCESS(0x400000) / OFFLINE(0x1000)
    # 任一置位 = 该文件是"仅在线"占位符(内容在云端,本地已脱水)
    attrs = entry.stat(follow_symlinks=False).st_file_attributes
    online_only = bool(attrs & (0x40000 | 0x400000 | 0x1000))
    # 结果:406,481 个文件里 406,076 个 online_only,仅 390 个本地有内容

    关键推理:

    一个文件能被脱水成”仅在线”占位符,前提是它已经成功上传到云端了。所以所有”仅在线”文件,定义上都是同步成功的。

    那么”上传失败”的文件,本地必然是”有内容”状态(不会被脱水)。而本地”有内容”的文件总共只有 390 个——若元凶是某个”上传失败”的文件,它必然落在这 390 个里。我把这 390 个全列出来,逐类排查:最近编辑过的正常文档、Git 仓库、GIS 数据、.DS_Store、会被 Dropbox 默认忽略的 ~$ Office 锁文件、几个自动化脚本留下的 .tmp……

    同时对全盘做了一次命名合规扫描(对照 Dropbox 官方的命名规则:不能含 < > : " | ? *、不能以空格/句点结尾、路径 < 260 等,见 Dropbox Help: Naming files and folders):

    • 非法字符:0
    • 尾部空格/句点:0
    • Windows 保留名:0
    • 大小写冲突:0
    • 以空格开头:10 个,但它们全是”仅在线”状态 = 早已同步成功
    • 超长路径(>250):769 个(多为 node_modules 深层嵌套),同样全是”仅在线” = 已同步

    换句话说,那些”看起来可疑”的文件,Dropbox 其实都已经顺利同步了。 这一步把嫌疑范围从 40 万骤降到 390 个本地文件——而这 390 个里也没发现任何卡住失败的项

    本回合小结 —— 观察到:可疑命名 / 超长路径的文件其实都是”仅在线”= 已同步,本地有内容的仅 390 个且无异常;排除了:存在大批因命名 / 路径而同步失败的文件;还不能证明:Dropbox 内部绝对没有任何挂起项——只能说在可读的本地证据里没发现。


    结论:一个陈旧的”幽灵徽标”

    把所有证据拼起来:

    检查项 结果
    Dropbox 面板 / 托盘 ✓ 一切正常,文件均为最新
    sync_history 0 错误,当天仍在正常同步
    主同步库 无错误字段;40.6 万文件已同步为”仅在线”
    本地未上传文件 仅 390 个,无任何卡住失败项
    命名合规 0 个硬性不兼容文件
    Windows 图标缓存 已重建,无效
    desktop.ini 指向干净图标,无辜
    注册表节点 红叉随节点删/恢复同步消失/重现 → 由 Dropbox 实时输出

    基于现有本地证据,没找到任何真正无法同步的文件。那个红叉更像是 Dropbox 文件资源管理器集成为根目录留下的一个”陈旧徽标”——它和 Dropbox 自己的引擎状态相矛盾,是显示层的 bug。很可能驻留在 Dropbox 自身的状态 / 缓存里(从”重启系统、重启 Dropbox、清 Windows 图标缓存、重置注册表节点全都无效”这一点反推),又由 Dropbox 实时喂给外壳扩展(所以注册表删了再恢复会立刻重现)。

    这类”引擎说 up to date、角标却卡在错误”的情况,在各家网盘里都不罕见(参见 Dropbox Help: 检查同步状态 以及社区里大量同类反馈)。


    收尾:一条命令搞定

    既然是 Dropbox 自己的状态缓存陈旧,正确做法不是再去碰 Windows,而是让 Dropbox 重算并重新推送徽标。Dropbox 官方排障步骤里就有”清空缓存文件夹”这一招,把这一招用上:.dropbox.cache 只是上传/下载用的临时暂存数据,删除不会动你的 Dropbox 正式文件,Dropbox 会按需自动重建它(Dropbox Help: Clear the cache folder)。下面的命令针对本机这种标准布局(个人账户、根目录在 %USERPROFILE%\Dropbox);团队账户或 File Provider 布局下缓存路径不同,需相应调整:

    # 1) 退出 Dropbox(官方做法是托盘菜单「退出」;强杀只是脚本化的便捷替代)
    Stop-Process -Name Dropbox -Force
    
    # 2) 清空内部缓存(不是你的文件;Dropbox 会自动重建)
    Get-ChildItem "$env:USERPROFILE\Dropbox\.dropbox.cache" -Force |
      Remove-Item -Recurse -Force
    
    # 3) 重启 Dropbox
    Start-Process "C:\Program Files (x86)\Dropbox\Client\Dropbox.exe"

    重启后 Dropbox 重新评估了根目录状态,红叉消失,图标恢复成干净的蓝色盒子。 收工。

    注:托盘菜单里的「暂停同步」→「恢复同步」对本案无效——这台机器此前已多次暂停/恢复,红叉依旧;只有清掉 .dropbox.cache、让 Dropbox 重建状态才奏效。可见这个广为流传的建议并非万能。


    几条可复用的经验

    1. 别被”显而易见的答案”骗了。 “网盘装太多,15 个覆盖图标名额被吃满”是本案最诱人的解释,而且数据初看完全吻合——但实测 explorer 已加载模块直接推翻了它。注册表占名额 ≠ 运行时真加载。
    2. 区分”显示层缓存”与”数据源实时输出”: 做”删除载体—恢复载体”对照实验。本案中红叉随注册表节点删/复而灭/现,直接证明它是 Dropbox 实时喂的。
    3. 善用”仅在线”占位符状态做反向推理: 能脱水 = 已上传成功。这一步把”40 万嫌疑文件”瞬间缩小到”390 个本地文件”,而这些里也查不出真正卡住的项。
    4. 修复要打在正确的层: 症状显示在 Windows 资源管理器,病根却在 Dropbox 的内部状态。对着 Windows 一通重启、清缓存、改注册表,都是在错误的层上使劲。
    5. 用户的直觉常常是对的: 他从一开始就说”Dropbox 其实没问题”。最终所有取证都指向同一结论——未发现任何实际同步失败的证据,红叉更像显示层的 bug,不影响文件同步。

    参考资料

    • Raymond Chen, *Why is there a limit of 15 shell icon overlays?* — The Old New Thing, Microsoft DevBlogs. [oldnewthing]
    • Tim Anderson, *The battle to own Windows Explorer shell overlay icons, or why your OneDrive green ticks have stopped working.* [itwriting]
    • Wikipedia, *List of shell icon overlay identifiers.* [wikipedia]
    • Gareth J. M. Saunders, *Managing overlay icons for Dropbox and TortoiseSVN and TortoiseGit.* [gareth]
    • ownCloud client, Issue #3141: *[Windows] Shell icon overlays take unwarranted precedence in registry list.* [owncloud]
    • CentreStack / Gladinet, *Why can’t I see any overlay icon on the files in the cloud drive?* [gladinet]
    • Dropbox Help, *How to clear the Dropbox cache folder.* [dropbox-cache]
    • Dropbox Help, *How to check if your files and folders are syncing.* [dropbox-sync-check]
    • Dropbox Help, *Naming Dropbox files and folders.* [dropbox-naming]

    *排查环境:Windows 11 Home (22631) · Dropbox 95.x · 同步约 40 万文件(Files On-Demand)· 同机并存 OneDrive / 百度网盘 / Adobe CoreSync。*


    致谢与署名

    本文由 Claude Code 实地探索并撰写初稿:从复现症状、逐层取证(重建图标缓存、解析覆盖图标注册表、检查 explorer 已加载模块、提取图标资源、读取 Dropbox 内部 SQLite 库、全盘只读元数据扫描),到最终定位与修复,全程留痕。网站管理员 oopus 在过程中做了若干关键的问题决断与验证(包括坚持”Dropbox 实际无故障”的判断、对动注册表/扫描等操作的把关与授权、以及”暂停/恢复同步无效”等一手事实的纠正)。最终的修订与审校由 oopuscodex(OpenAI Codex)共同完成——codex 对技术准确性、逻辑严谨度与引用规范做了一轮严格 review,促成了多处”把’很像’收紧为’已证实’”的改写。

  • Documents folder in Windows

    In the Windows system, there are likely up to four different types of ‘Documents’ that you can find in your Windows system:

    In your local user account folder:

    x:\Users\{user}\Documents\

    In your OneDrive private user account folder:

    C:\Users\{user}\OneDrive\document

    In your OneDrive organization user account folder:

    C:\Users\sudos\OneDrive – Harvard University\Documents

    In the Documents shortcut (this shortcut links to the first user account folder you logged in):

    Documents

  • Wake Me up When September Ends

    一年前的九月三十號,某個文件被寫定(下圖下方紅框),某個人關掉了 ssh,之後再沒有人維護過這個 service。直到一年之後的八月底,它像個沒人要的孩子,滿身創傷,再也無法提供服務,也沒有人…… 九月一號,理清了服務器上的所有細節,一點點修復了代碼的所有問題,某個文件被寫定(下圖上方紅框),存盤。註定似的電台裡面響起了 Wake Me up When September Ends

  • Locale Emulator 的 global profile 不能用,但是 application profile 可以用的解决方法

    到程序目录下找到主程序:X:\Program Files (x86)\Locale.EmulatorXXX\LEProc.exe, 赋予 管理员权限即可。