OneDrive「按需文件」与业务应用 ── 占位符打破的前提与对策

· · OneDrive, 按需文件, KFM, Windows, 业务应用, 云端存储, 文件系统, 故障调查, 信息系统

「业务应用读不了存在桌面上的 CSV。」「换电脑之后,以前能用的导入以『找不到文件』失败。」「资源管理器看得到文件,从应用开启却出错。」── 这几年,这类来自客户的咨询已成定番。

调查之后,原因往往不是应用程序错误,而是 OneDrive 的「桌面与文档自动备份」(已知文件夹搬移,KFM)与「按需文件」。真正的桌面已搬到 C:\Users\<名称>\OneDrive\Desktop,你在那里看到的文件有一部分是没有本机内容的「占位符」。使用者和 IT 都没注意到这项变化,继续用这台电脑。

换句话说,业务应用「文件在本机磁盘上」的隐含前提,在没有人做决定的情况下,已被「文件在云端,本机只有外表」这个前提取代。本文以中小企业的信息系统人员与 Windows 应用开发者为对象,依 Microsoft Learn 第一手资料整理占位符如何运作、如何从文件属性判断状态、业务应用踩到的典型陷阱、开发端与 IT 端各自能做的事,以及接到「文件打不开」时的分流程序。

业务应用隐含前提的替换文件在本机磁盘上这个业务应用的隐含前提,在没有人做决定的情况下,已被实体在云端、本机只有外表这个前提取代以往的隐含前提实体在本机磁盘上被取代后的前提实体在云端本机只有外表占位符

图 1: 「实体在本机」这个前提,在没有人做决定的情况下,已被「实体在云端,本机只有外表」取代。

1. 先讲结论

  • 桌面、文档、图片可能已被 KFM 搬到 C:\Users\<名称>\OneDrive\ 底下。 新电脑初始设定时很容易被打开,组织也能用策略一次套用。假设固定路径的应用会在这里坏掉。1
  • 目前的同步应用默认开启按需文件。 在其他设备或网页上建立的文件,会以没有本机内容的「仅联机」占位符出现。23
  • 占位符的真正身分是 Cloud Files API 管理的重解析点(cldflt.sys 微型筛选器)。 对资源管理器与文件 API 都像普通文件,开启就会自动下载(水合)。4
  • 状态可从文件属性判断。 FILE_ATTRIBUTE_OFFLINE、RECALL_ON_DATA_ACCESS、PINNED、UNPINNED 等是标记,attrib 命令以 O、P、U 字母显示。只检查属性不会引发下载。567
  • 业务应用的典型事故是「打不开」、「变慢」、「误判属性」、「监视事件风暴」、「与同步冲突」的组合。 离线或 OneDrive 停止时水合失败,批次处理会诱发每个文件的下载。48
  • 应用端的对策是「尊重占位符」。 基本做法是枚举时用属性判断、不要轻易开启,必要时用 FILE_FLAG_OPEN_NO_RECALL,不要把文件夹放在 OneDrive 底下。910
  • IT 端的对策是「用固定运营」与「用策略控制」。 用「始终保留在此设备上」为业务文件夹保证实体,并用组策略 / Intune 刻意配置 KFM 与按需文件。别忘了存储感知也能「把未使用的文件退回仅联机」。1112

一句话:「资源管理器看得到的文件」与「本机磁盘上有实体的文件」已不再是同一件事

2. 正在发生什么 ── KFM 与按需文件

2.1. 桌面可能已不是 C:\Users\<名称>\Desktop

OneDrive 同步应用有一项称为已知文件夹搬移(KFM)的功能。设置界面显示为「备份」、「备份重要文件夹」等;开启后,真正的桌面、文档、图片会被搬移(重新导向)到 OneDrive 文件夹底下1

使用者看到的位置 KFM 前的实际路径 KFM 后的实际路径
桌面 C:\Users\taro\Desktop C:\Users\taro\OneDrive\Desktop
文档 C:\Users\taro\Documents C:\Users\taro\OneDrive\Documents
图片 C:\Users\taro\Pictures C:\Users\taro\OneDrive\Pictures

新电脑初始设定(OOBE)以 Microsoft 帐户或公司帐户登入时,文件夹备份常被当成默认提案,照著往下走就会开启。组织也能用「以静默方式将 Windows 已知文件夹移到 OneDrive」策略(KFMSilentOptIn)不问使用者就一次套用111

KFM 被开启的两条路径新电脑初始设定以帐户登入时,文件夹备份会被当成默认提案,照著往下走就会开启;在组织里 KFMSilentOptIn 策略会不问用户就一次套用新电脑的初始设定以帐户登入默认提出备份照著往下走就开启组织策略KFMSilentOptIn不问使用者就一次套用KFM 开启

图 2: KFM 会在没人注意的情况下开启,来源是初始设定的默认提案,或组织的无讯息套用策略。

尴尬之处在于 资源管理器的外表几乎不变。外壳已知文件夹 API(SHGetKnownFolderPath 与 .NET 的 Environment.GetFolderPath)会回传搬移后的正确路径,所以守规矩的应用会继续运作。坏掉的是 在配置文件或代码里写死 C:\Users\%USERNAME%\Desktop 这类固定路径的应用。换电脑后导入以「找不到文件」失败的典型模式就是这个。

KFM 之后应用如何解析路径KFM 把真正的桌面等文件夹搬到 OneDrive 底下后,使用已知文件夹 API 的应用会以搬移后的正确路径继续运作,但写死固定路径的应用会找不到文件已知文件夹 API写死的固定路径KFM 已开启真正的桌面等搬到 OneDrive 底下应用如何解析路径?取得搬移后的正确路径并继续运作找不到文件

图 3: KFM 之后,使用已知文件夹 API 的应用会继续运作,但写死固定路径的应用会在这里坏掉。

2.2. 按需文件 ── 看得到,但没有实体

另一条线索是按需文件。在开启的环境里,OneDrive 上的每个文件都在资源管理器里看得到,但 内容要等到文件被开启才下载。这项功能在目前的同步应用里默认开启,Microsoft 也建议维持开启。23

状态可从资源管理器的状态图示分辨。13

图示 状态 本机内容
云朵标记 仅联机 无(只有占位符)
白底勾选 本机可用 有(之后可能被自动释放)
绿底白勾 始终保留在此设备上(固定) 有(不在自动释放范围)

这里重要的是中间状态。开过一次、已有本机内容的文件,可能因使用者的「释放空间」或稍后会谈到的存储感知 再变回仅联机。这是「上个月还能用」这类难以重现故障的原因之一。312

按需文件的三种状态与转换仅联机的文件开启后会变成本机可用,但释放空间或存储感知可把它退回仅联机,只有固定的文件不在自动释放范围内开启(水合)释放空间存储感知始终保留在此设备上始终保留在此设备上取消固定仅联机(云朵标记)本机可用固定(始终保留在此设备上)

图 4: 按需文件的三种状态。「本机可用」可能自动退回仅联机;固定不在该范围内。

3. 占位符的真正身分 ── Cloud Files API 与重解析点

按需文件实作在 Windows 10 版本 1709 引入的 OS 机制 Cloud Files API 之上。文件系统端的工作单位是名为 cldflt.sys 的文件系统微型筛选器(服务名称 CldFlt,「Windows Cloud Files Filter Driver」),OneDrive 是使用此 API 的「同步提供者」之一。47

占位符在技术上是 重解析点。文件系统上只有档名、大小、时间戳等元数据(约 1KB),没有内容数据。应用开启文件并读取时,微型筛选器侦测到要求,指示同步提供者传输数据,等下载完成后读取才继续。这次获取称为 水合(hydration);丢掉本机内容、回到占位符称为 脱水(dehydration)4

开启占位符时的水合应用开启占位符并读取时,cldflt.sys 微型筛选器侦测要求,指示同步提供者传输数据,等下载完成后读取才继续同步提供者cldflt.sys 微型筛选器业务应用同步提供者cldflt.sys 微型筛选器业务应用开启并读取的要求指示数据传输下载完成读取继续

图 5: 占位符的读取,是在微型筛选器让同步提供者抓回数据之后才继续。

听到「重解析点」会担心与「侦测到重解析点就特别处理」的既有代码相容,但为了相容,Cloud Files API 对同步引擎与 %systemroot% 底下以外的所有人隐藏它是重解析点这件事。对普通应用来说,它看起来像「只是开启稍微慢一点的普通文件」。这种彻底的透明既方便,也是「应用在没注意到的情况下被打破前提」的原因。4 重解析点本身的机制在「NTFS 内部结构」说明。

隐藏重解析点,以及看起来的差异占位符的真正身分是重解析点,但 Cloud Files API 对同步引擎以外的程序隐藏此事,因此对普通应用看起来只是开启稍微慢一点的普通文件同步引擎等其他应用占位符(重解析点)是哪个程序开启的?可见为重解析点看起来像普通文件看起来只是开启稍慢

图 6: 它是重解析点这件事对同步引擎以外的所有人隐藏,对普通应用看起来像普通文件。

在资源管理器属性中,占位符的特征是 「大小」显示原始大小,而「磁盘上的大小」几乎是 0。「有大小,所以一定有实体」这个假设在这里不成立。

占位符在属性中的样子在资源管理器属性中,占位符的大小显示原始大小,磁盘上的大小几乎是 0,因此有大小就一定有实体的假设不成立占位符内容大小是原始大小磁盘上的大小几乎是 0一定有实体的假设没有本机内容

图 7: 占位符的「大小」显示原始大小,而「磁盘上的大小」几乎是 0。

4. 文件属性会告诉你状态

占位符状态以普通文件属性公开。主要如下。5

属性 意义
FILE_ATTRIBUTE_OFFLINE 0x00001000 数据无法立即使用(分层式存储管理的传统属性)
FILE_ATTRIBUTE_RECALL_ON_OPEN 0x00040000 没有实体本机内容。只出现在目录枚举结果
FILE_ATTRIBUTE_PINNED 0x00080000 使用者意图「一律留在本机」(固定)
FILE_ATTRIBUTE_UNPINNED 0x00100000 不必保留本机内容(改成仅联机的意图)
FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS 0x00400000 部分或全部内容不在本机。读取会从远端获取

命令提示字元的 attrib 命令可用单一字母显示与设定这些属性。O 是离线属性,P 是固定,U 是取消固定。6 与 OneDrive 按需文件状态的对策,Microsoft 文件整理如下。7

按需文件状态 属性 设定命令
一律可用(固定) Pinned(显示 P) attrib +p <path>
本机可用 既非 P 也非 U attrib -p <path>
仅联机 Unpinned(显示 U) attrib +u <path>

有一点要注意。切换状态有顺序。 想把仅联机(U)的文件变成「本机可用」时,只跑 -p 会留下 U,实体不会被抓回来。Microsoft 文件也示范先做 +p(一律可用)下载实体,再做 -p 的程序。7 在必须可靠切换既有状态的脚本里,较安全的做法是像 attrib +p -u 这样 同时清掉相反属性

从仅联机切到本机可用的顺序对仅联机的文件只运行 attrib -p 会留下 U 属性且不会抓回实体;需要先用 attrib +p 下载实体再做 -p只做 attrib -pattrib +pattrib -p仅联机(U)维持 U;实体未被抓回固定(下载实体)本机可用

图 8: 从仅联机切换,需要先用 +p 抓回实体,再做 -p 的顺序。

PowerShell 判断的例子。只看属性不会引发水合,因此可放心用于调查与批次检查。

function Test-CloudPlaceholder {
    param([Parameter(Mandatory)][string]$Path)

    $value = [int](Get-Item -LiteralPath $Path -Force).Attributes

    [pscustomobject]@{
        Path               = $Path
        Offline            = ($value -band 0x00001000) -ne 0  # FILE_ATTRIBUTE_OFFLINE
        RecallOnDataAccess = ($value -band 0x00400000) -ne 0  # 内容并非全部在本机
        Pinned             = ($value -band 0x00080000) -ne 0  # 始终保留在此设备上
        Unpinned           = ($value -band 0x00100000) -ne 0  # 仅联机
    }
}

# 批次检查文件文件夹底下的 CSV(不会下载内容)。
# 用已知文件夹 API 解析路径。把显示名称
# "Documents" 写死,可能因实际文件夹名称
# (Documents 对上本地化名称)与 KFM 配置
# 而变成不存在的路径
Get-ChildItem ([Environment]::GetFolderPath('MyDocuments')) -Recurse -Filter *.csv |
    ForEach-Object { Test-CloudPlaceholder $_.FullName } |
    Where-Object RecallOnDataAccess |
    Format-Table -AutoSize

转成 [int] 是因为 .NET 的 FileAttributes 枚举没有定义 RECALL_ON_DATA_ACCESS 这类名称。对数值做位元运算就能顺利判断。

5. 业务应用踩到的陷阱

这是本题。占位符的透明大多数时候很方便,但与典型业务应用处理模式叠在一起,会以以下六种形状浮现。

5.1. 开启就立刻开始下载 ── 离线时「打不开」

开启仅联机的文件会当场开始水合。线上、文件又小,快到你不会注意到,但 当 OneDrive 停止、登出或暂停、网络不稳、或文件很大时,就变成「文件存在但打不开」。错误可能以 ERROR_CLOUD_FILE_PROVIDER_NOT_RUNNING(0x8007016A,”The cloud file provider is not running”)这类云端文件系列代码回来,也可能在应用端被观察成逾时。8

更进一步的陷阱是,相当于 File.Exists() 的存在检查,以及取得属性或大小,都会成功。你会得到本机磁盘直觉解释不了的错误模式:「存在检查过了,读取却失败」。

访问仅联机文件时的分支存在检查与取得属性、大小会成功,但读取内容会开始水合;若 OneDrive 在运行且网络正常,下载后可读,否则以 0x8007016A 等错误或逾时失败存在检查,或取得属性或大小成功读取内容开始水合OneDrive 在运行且网络正常?下载后可读0x8007016A 等错误,或逾时

图 9: 存在检查可以成功,读取却失败。成败取决于 OneDrive 是否在运行,以及网络。

5.2. 批次处理诱发每个文件的下载

把读取文件夹内每个文件的批次、哈希计算、全文搜寻或自制备份对准 OneDrive 底下的树,你碰到的每个文件都会被诱发水合。对数 GB 的文件夹,处理会异常变慢,下载也会填满磁盘,低容量电脑上空间不足会引出另一种故障。按需文件原本要省下的容量,一次全扫描就没了。

此外,若应用在没有明确使用者操作的情况下引发水合,Windows 可能显示Toast并让使用者选择封锁。一旦封锁,该应用之后的下载会持续失败(可在设定的「自动下载文件」解除)。这是「只有某台电脑导入失败」的原因之一。4

批次处理如何诱发每个文件的下载OneDrive 底下的批次会诱发碰到的每个文件水合,造成处理延迟与磁盘压力,若使用者在Toast上封锁,之后下载会持续失败OneDrive 底下的批次碰到的每个文件都水合处理延迟与磁盘压力可能出现Toast使用者封锁了吗?之后下载持续失败下载继续

图 10: 批次会诱发每个文件水合,若在Toast上被封锁,之后失败会持续。

5.3. 没预期这些属性的代码的误动作

不知道 FILE_ATTRIBUTE_OFFLINE 或 RECALL_ON_DATA_ACCESS 的代码,会在意想不到的地方误动作。

  • 属性用完全相等测试(attributes == FileAttributes.Archive 等),占位符被当成「非预期文件」排除或当错误处理
  • 备份或同步工具的排除判断把 OFFLINE 属性解读成「已送到磁带」而略过(或反过来,把本该排除的每个文件都抓回来)
  • 只读检查或封存位元操作破坏属性组合
没预期属性的代码的误动作模式不知道占位符属性的代码,会因完全相等属性测试而排除或当错误、因误解 OFFLINE 而略过或全抓、或因属性操作破坏组合而误动作没预期属性的代码完全相等测试误解 OFFLINE属性操作破坏组合被当成非预期而排除或出错略过,或全部抓回

图 11: 不知道 OFFLINE 或 RECALL 系列属性的代码,会以排除、错误略过或属性破坏的方式误动作。

Microsoft 给微型筛选器开发者的指引明白写道:不应对带有 RECALL_ON_DATA_ACCESS 的文件发出轻率的读写。文件针对核心驱动程序,但「碰到带此属性的文件内容 = 发生获取成本」这个原则,原封不动适用于使用者模式应用。10

5.4. FileSystemWatcher 与同步的交互作用

FileSystemWatcher 监视 OneDrive 底下的文件夹,你得到的不只是使用者操作,还有 同步应用活动带来的大量事件。其他设备的变更每次同步、水合或脱水每次改变属性或大小,都可能发出 Changed 事件。再者,把监视并导入的结果写回同一文件夹的设计,会在写入 → 上传 → 属性更新 → 另一个事件的回圈里变成「变更通知风暴」。事件节流与实体检查的设计见「FileSystemWatcher 的使用方法与注意事项」,但在 OneDrive 底下,这项需求又高一阶。

监视并写回造成的变更通知回圈若收到变更事件的监视应用把导入结果写回同一文件夹,同步应用的上传与属性更新会再发出事件,形成变更通知风暴的回圈变更事件监视应用导入写回同一文件夹同步应用上传属性或大小被更新其他设备变更的同步

图 12: 把导入结果写回同一文件夹,会变成同步应用活动再产生事件的回圈。

5.5. 独占锁期间的同步冲突,以及「副本」文件

业务应用以独占锁开启文件期间,同步应用无法上传或更新该文件。把长时间持锁的应用(Access .accdb、自制格式数据档、日志文件等)放在 OneDrive 底下,同步错误会变成常态。反过来说,同一文件在多台电脑上编辑时,同步应用会试著两边都留,并产生带电脑名称的重复档,或「— 副本」这类冲突副本。假设「一个文件夹、一个文件」的导入会在这份重复上误动作。锁定设计的基础见「文件集成互斥控制基础知识」。

独占锁与多机编辑造成的同步问题应用以独占锁开启文件期间同步应用无法更新,同步错误变成常态;同一文件在多台电脑编辑会产生冲突副本,一个文件夹一个文件的假设崩解应用以独占锁开启无法同步;同步错误成常态同一文件在多台电脑编辑产生冲突副本带电脑名称或副本的重复一个文件夹一个文件的假设崩解

图 13: 独占锁让同步错误成常态,多台电脑编辑则因冲突副本引出误动作。

5.6. 杀毒与搜索索引器诱发水合

读取文件内容的不只是业务应用。杀毒软件的全盘扫描与搜索索引器,只要碰到占位符的内容也会诱发水合。Microsoft Defender 等产品在按需扫描时会略过带 RECALL_ON_DATA_ACCESS 属性的文件,但那是产品端的对策,不能假设每个安全产品都会同样小心。若看到「每晚扫描时网络与磁盘都被打满」或「本该仅联机的文件到早上已全部落地」这类症状,就怀疑这条线。14

安全产品或搜索索引器诱发的水合全盘扫描或搜索索引器碰到占位符内容时,尊重 RECALL 属性的产品会略过,不尊重的产品会让每个文件水合,造成夜间频宽压力或早晨落地尊重的产品不尊重的产品全盘扫描或搜索索引器尊重 RECALL 属性吗?略过占位符碰到内容并水合夜间频宽与磁盘被打满到早上文件已全部落地

图 14: 不尊重属性的扫描会诱发每个文件水合,并以夜间负载或早晨落地显现。

6. 应用开发端的对策 ── 尊重占位符

作为开发者的基本方针,是把占位符当成 「有获取成本的文件」而不是「坏掉的文件」

  • 枚举时用属性判断,不要轻易开启。 文件夹扫描时,先从属性(第 4 章的判断)确认是否仅联机,只开启你需要内容的文件。对「缺了也不致命」的处理 ── 日志收集、哈希计算、预览生成 ── 给略过占位符的选项。
// 把 .NET 的 FileAttributes 未定义的值用数字定义
const FileAttributes RecallOnDataAccess = (FileAttributes)0x00400000;
const FileAttributes RecallOnOpen       = (FileAttributes)0x00040000;

static bool IsCloudPlaceholder(FileAttributes attributes) =>
    (attributes & (RecallOnDataAccess | RecallOnOpen | FileAttributes.Offline)) != 0;

foreach (var file in new DirectoryInfo(watchFolder).EnumerateFiles("*.csv"))
{
    if (IsCloudPlaceholder(file.Attributes))
    {
        log.Warn($"{file.Name} 仅联机;这次略过");
        continue;
    }
    Import(file.FullName);
}
枚举时用属性判断再开启的路径文件夹扫描时先在枚举确认属性;若是占位符就略过并留警告记录,只对其他文件运行导入,以免轻率水合枚举时确认属性占位符?略过并留警告记录运行导入只开启需要内容的文件的方针

图 15: 枚举时用属性判断,略过占位符而不开启,以免轻率水合。

  • 注意 FILE_FLAG_OPEN_NO_RECALL 不是「不要下载」的保证。 在 CreateFile 指定此标志,可表示「取得的数据应留在远端、不要写回本机存储」的意图。不过它只是 不要让取得的数据驻留本机的标志;若你读内容,数据传输本身仍会发生。若要避开频宽与延迟本身,只用属性、大小、时间戳结束 ── 不要要求读取访问(以访问权限 0 开启,或用枚举结果的元数据)。那才最安全。9
FILE_FLAG_OPEN_NO_RECALL 的效果与界限FILE_FLAG_OPEN_NO_RECALL 是不让取得的数据驻留本机的标志;若读内容,数据传输本身仍会发生,因此若要避开传输,最安全是只用属性等元数据结束以 NO_RECALL 标志开启读取内容发生数据传输不会驻留本机只用元数据结束不发生传输;最安全

图 16: FILE_FLAG_OPEN_NO_RECALL 只避免驻留本机;若要避开传输本身,只用元数据结束。

  • 在错误讯息里写「这在 OneDrive 底下」。 读取失败时,只要确认目标路径是否在 %OneDrive% 底下并写进讯息,现场与帮助台的分流时间就会大幅缩短。若侦测到 0x8007016A 这类云端文件系列错误,理想是告诉使用者「请检查 OneDrive 的状态」。
  • 不要把应用的文件夹放在 OneDrive 底下。 在 KFM 环境,「文件」也在 OneDrive 底下。把应用的设定、数据库、工作档放在 %ProgramData%%LocalAppData%不要把桌面或文件选成默认存储位置或默认导入文件夹。决定放哪里,见「Windows应用的数据存储位置怎么选」。
  • 决定使用者选了 OneDrive 底下位置时的行为。 对让使用者选择存储位置的应用,事先在规格里纳入设计决策,例如所选路径在 OneDrive 底下(OneDrive / OneDriveCommercial 环境变量的路径底下)时警告,或只拒绝放置锁定档或数据库。

7. IT 端的对策 ── 用固定与策略控制

从 IT 的位置,务实的运营不是「整段关掉按需文件」,而是 只在业务需要的地方保证实体

  • 固定业务应用会读的文件夹。 从资源管理器右键选单选「始终保留在此设备上」,或在映像脚本运行 attrib +p -u <folder> /s /d(同时指定 -u,才能把已是仅联机的文件可靠切到固定)。固定的文件在本机保证有实体,也不在稍后谈到的自动转成仅联机的范围内。72
  • 刻意配置 KFM 与按需文件,而不是「注意到时已经开著」。 主要策略(组策略 / Intune)如下。111
目的 策略(注册表值) 效果
控制按需文件 Use OneDrive Files On-Demand (FilesOnDemandEnabled) 开:新使用者默认仅联机。关:传统完整同步
一次套用 KFM Silently move Windows known folders to OneDrive (KFMSilentOptIn) 不经使用者操作就搬移桌面等
禁止 KFM Prevent users from moving their Windows known folders to OneDrive (KFMBlockOptIn) 禁止搬移已知文件夹
禁止关掉 KFM Prevent users from redirecting their Windows known folders to their PC (KFMBlockOptOut) 禁止使用者关掉
降低小组网站容量 Convert synced team site files to online-only (DehydrateSyncedTeamSites) 把已同步的小组网站改成仅联机(注意它朝实体消失的方向作用)
  • 了解存储感知如何移动。 存储感知有一项功能,把若干天未开启的云端文件自动退回仅联机,天数可用策略(ConfigStorageSenseCloudContentDehydrationThreshold)设定。默认是 0(不自动退回),但若使用者从设置界面开启,或组织为低容量设备设定了,则「上周开过的文件变回云朵图示」会当正常行为发生。固定的文件不在范围内,所以「固定业务文件夹」在这里也有效。122
存储感知自动转成仅联机的分支在存储感知的自动释放中,固定的文件不在范围内且实体保留;未固定且若干天未开启的文件会被退回仅联机存储感知自动释放已固定?不在范围内;实体保留若干天未开启?退回仅联机实体保留默认 0 不自动退回

图 17: 存储感知把若干天未开启的文件退回仅联机,但固定不在范围内。

  • 停用按需文件前先估计影响。 停用 FilesOnDemandEnabled 会变成传统完整下载同步,但磁盘消耗与第一次同步的频宽负载会跳升。Microsoft 建议维持开启,停用应视为确认「目标使用者数据量小」与「磁盘有余裕」之后的有限措施。112
  • 写进支援程序。 把下一章的分流程序放进「桌面上的文件打不开」问询模板,即使经办人换了,应对质量也能维持。

8. 分流程序 ── 接到「文件打不开」时

接下咨询时,由上往下确认。

# 要确认的事 方法 你会知道的事
1 路径在 OneDrive 底下吗? echo %OneDrive% 确认同步根并对上目标路径。也在资源管理器地址栏确认「桌面」的实际路径 KFM / OneDrive 是否介入
2 文件的状态 attrib <path> 确认 U(仅联机)、P(固定)、O。也看内容的「磁盘上的大小」 实体是否在本机,或是占位符
3 OneDrive 是否在运行 任务栏图示(已登入、暂停、错误)、Get-Process OneDrive 水合是否可能。0x8007016A 典型是停止或配置错误8
4 网络 公司代理、频宽、到 OneDrive 服务的可达性 下载本身是否可能
5 磁盘可用空间 目标卷的可用空间。容量低时也有 OneDrive 阻挡下载的策略 水合失败的另一因素
6 失败纪录 记下应用的错误码与发生时间,对上同步应用的错误显示 是应用端问题还是 OneDrive 端问题

权宜办法是对目标文件夹按右键,选「始终保留在此设备上」(或 attrib +p /s /d)。这样实体会在本机排齐,业务可以恢复。在此之上,再决定本质原因在应用端(第 6 章)还是 IT 端(第 7 章),作为永久对策。

从权宜到永久对策的路径权宜办法是把目标文件夹设成始终保留在此设备上,实体在本机排齐后业务可恢复;在此之上决定本质原因在应用端还是 IT 端,再进入永久对策应用端IT 端权宜固定实体在本机排齐业务恢复本质原因在哪?到第 6 章的对策到第 7 章的对策

图 18: 权宜是固定、排齐实体、恢复业务;永久对策在决定是应用端还是 IT 端之后进行。

若确认到这里,「路径不在 OneDrive 底下」且「也不是占位符」,就往共享文件夹或路径长度等其他定番原因走。「网络磁盘机与 UNC 路径的陷阱」与「MAX_PATH 与 Windows 路径・文件名称的陷阱」是接下来的地图。

9. 总结

  • KFM 可能已把真正的桌面、文档、图片搬到 C:\Users\<名称>\OneDrive\ 底下。假设固定路径的应用会在这里坏掉。用已知文件夹 API 解析是第一步。
  • 按需文件默认开启,没有本机内容的占位符理所当然存在。占位符是 Cloud Files API(cldflt.sys)的重解析点,开启就会自动水合。
  • 状态可从文件属性(OFFLINE / RECALL_ON_DATA_ACCESS / PINNED / UNPINNED)判断,在 attrib 显示为 O、P、U。只检查属性不会引发下载。
  • 业务应用事故呈现为离线时水合失败、批次处理的完整下载、没预期属性的代码、FileSystemWatcher 与同步的交互、独占锁与同步的冲突,以及安全产品诱发的水合。
  • 应用端的基本是「用属性判断、不要轻易开启」、「不要把文件夹放在 OneDrive 底下」、「出错时说它在 OneDrive 底下」。
  • IT 端用「固定业务文件夹」与「KFM、按需文件、存储感知的策略控制」做出预期状态。
  • 分流可依路径 → attrib → OneDrive 运行 → 网络 → 可用空间 → 纪录的顺序机械地走完。

下次接到「文件在那里但打不开」,先问这个。

那个文件真的在本机磁盘上吗?还是只有云端的外表坐在那里?

相关文章

相关咨询领域

小村软件有限公司处理与 OneDrive、云端存储有关的业务应用故障调查 ── 「以前能用的导入换电脑后就不能用」、「只有某台电脑打不开文件」── 假设占位符的文件处理与监视处理的设计与修正,以及 KFM / 按需文件环境下存储位置设计的审查。从厘清症状开始也没关系 ── 欢迎联系。

参考链接

  1. Microsoft Learn, Redirect and move Windows known folders to OneDrive. KFM 把桌面、文件、图片搬到 OneDrive 底下,以及提示、无讯息套用、禁止关闭、禁止搬移等原则。  2 3 4

  2. Microsoft Learn, Recommended sync app configuration. 按需文件默认开启且建议维持开启,以及存储感知会清理「未固定的本机可用文件」。  2 3 4 5

  3. Microsoft Support, Save disk space with OneDrive Files On-Demand for Windows. 按需文件的三种状态,以及「始终保留在此设备上」与「释放空间」操作。  2 3

  4. Microsoft Learn, Build a Cloud Sync Engine that Supports Placeholder Files. Cloud Files API 概观、占位符只持有约 1KB 元数据且开启会自动水合、重解析点对同步引擎与 %systemroot% 以外的程序隐藏,以及背景水合的Toast与封锁。  2 3 4 5 6

  5. Microsoft Learn, File Attribute Constants. FILE_ATTRIBUTE_OFFLINE、RECALL_ON_OPEN、RECALL_ON_DATA_ACCESS、PINNED、UNPINNED 的定义与值。  2

  6. Microsoft Learn, attrib. attrib 命令语法,以及包含 O(离线)、P(固定)、U(取消固定)的属性标志。  2

  7. Microsoft Learn, Query and set Files On-Demand states in Windows. 用 attrib 确认按需文件状态,以及用 +p、-p、+u 设定,还有 CldFlt 服务。  2 3 4 5

  8. Microsoft Learn, Error 0x8007016a when copying files in OneDrive. 错误 0x8007016A “The cloud file provider is not running” 在 OneDrive 配置错误或停止时发生,以及解决步骤。  2 3

  9. Microsoft Learn, CreateFileW function (fileapi.h). FILE_FLAG_OPEN_NO_RECALL 是表示「要求的数据应留在远端、不要传回本机存储」的标志(不阻止取得数据本身),以及以访问权限 0 开启来取得属性。  2

  10. Microsoft Learn, Handling placeholders. 占位符应设定 FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS,以及对带此属性的文件轻率读写会招来不必要的水合或数据损毁。  2

  11. Microsoft Learn, IT Admins - Use OneDrive policies to control sync settings. 用 GPO/Intune 设定 OneDrive 同步应用的策略,包括 FilesOnDemandEnabled、KFMSilentOptIn、KFMBlockOptIn、KFMBlockOptOut、DehydrateSyncedTeamSites。  2 3 4

  12. Microsoft Learn, Policy CSP - Storage. 存储感知可把若干天未开启的云端文件改成仅联机、默认 0(不自动退回),以及 0–365 天的设定。  2 3

  13. Microsoft Support, What do the OneDrive icons mean?. 资源管理器显示的云朵与勾选等状态图示的意义。 

  14. Microsoft Learn, Plan for an Azure File Sync deployment. 杀毒扫描可能造成带 RECALL_ON_DATA_ACCESS 属性的文件被召回,以及 Microsoft Defender 等产品在按需扫描时会略过带此属性的文件。 

共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。

与本文相近的主题页面。以本文为起点,可以进一步了解相关服务和其他文章。

本文与以下服务页面相关联,欢迎从最接近的入口查看。

常见问题

汇总了咨询这一主题时常见的问题。

业务应用说「找不到文件」,读不了放在桌面上的 CSV。为什么?
多数情况是桌面文件夹本身已被 OneDrive 的已知文件夹搬移(KFM)移到 C:\Users\<使用者名称>\OneDrive\Desktop,或文件已变成仅联机的占位符。假设固定路径如 C:\Users\<使用者名称>\Desktop 的应用,搬移后就找不到文件。即使路径正确,OneDrive 停止或网络不稳时,仅联机的文件也可能打不开。先确认目标路径是否在 OneDrive 底下,并用 attrib 命令检查是否有 U(仅联机)。权宜办法是在右键选单选「始终保留在此设备上」,把实体留在本机。
程序能判断文件是否仅联机吗?
可以。仅联机的占位符带有 FILE_ATTRIBUTE_OFFLINE 与 FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS(0x00400000)等属性,因此不必下载内容就能从文件属性判断状态。取得属性或枚举文件夹不会引发水合(下载)。在 .NET 里有些值未定义于 FileAttributes,因此要转成整数再用位元运算检查。若确实需要开启但不读内容,也可用 CreateFile 的 FILE_FLAG_OPEN_NO_RECALL 这类手段。
关掉按需文件就能解决问题吗?
把关闭当成最后手段。关掉后同步范围内的每个文件都会下载到本机,磁盘容量与第一次同步的网络负载都会变大,Microsoft 也建议维持开启。实践上较有弹性的做法是只把业务应用会读的文件夹设成「始终保留在此设备上」(固定)。更根本、也更可靠的修正,是重新设计,让应用的文件夹与导入文件夹不要落在 OneDrive 管理之下。
我设了「始终保留在此设备上」,有些文件最后还是变回云朵图示。为什么?
先用 attrib 命令确认文件真的有固定(P 属性)。已固定的文件不在存储感知自动转成仅联机的范围内,但只因有人开启而「本机可用」、并未固定的文件,可能依存储感知设定与策略在一段时间后回到仅联机。使用者自己的「释放空间」操作,以及把小组网站文件改成仅联机的策略(DehydrateSyncedTeamSites),也会让云朵图示回来。业务上必须留在本机的文件夹,请以文件夹范围固定来运营。

作者简介

本文作者的个人简介页面。

Go Komura

小村软件有限公司 代表

以 Windows 软件开发、技术咨询与故障排查为中心,擅长难以复现的故障调查,以及既有资产仍在运行的项目。

返回博客列表