vscode 1.86+ 要求插件在 package.json 中显式声明 "capabilities": { "workspace": { "read": true, "write": true } },否则 vscode.workspace.fs api 静默失败;wsl 下必须禁用 node.js fs 并启用 metadata 挂载选项;路径授权不继承,每次新路径需重新授权。

vscode.workspace.fs 调用静默失败,先查 package.json 的 capabilities 声明
VSCode 1.86+ 版本起,vscode.workspace.fs.readFile()、vscode.workspace.fs.writeFile() 这类 API 不再容忍“能力缺失”。没声明,就直接失败——不报错、不弹窗、不提示,只返回 OperationNotSupportedError 或空 Promise。这不是你代码写错了,是平台在拦截。
必须在插件 package.json 中显式声明:
"capabilities": { "workspace": { "read": true, "write": true } }
注意:"workspace": true 已弃用,仅写 "workspace": { "read": true } 是合法的,但若你要保存到用户选中的任意路径(比如通过 vscode.window.showSaveDialog()),"write": true 不可省略。
常见踩坑点:
- 声明了
"workspace",但没触发路径授权弹窗 → 用户根本没点“允许”,后续所有读写都失败 - 硬编码路径如
vscode.Uri.file('C:\temp\config.json')→ 即使声明了能力,也因未获该路径授权而被拒 - 误以为“工作区根目录授权 = 子目录自动授权” → 实际上
C:\proj\src和C:\proj\dist是两个独立路径域,各自需单独授权
WSL 下必须禁用 Node.js fs,统一走 vscode.workspace.fs
在 WSL 环境中,直接用 fs.readFileSync() 读取 /mnt/c/Users/xxx/project/file.txt 极大概率失败:权限映射错乱、执行位丢失、甚至返回 EPERM。这不是插件 bug,是跨文件系统元数据不兼容导致的。
正确做法只有一条:全程使用 vscode.workspace.fs API。它内部做了 WSL 兼容层,能正确处理 Windows 路径归属、UID/GID 映射和 ACL 透传。
同时确认 WSL 配置已启用元数据支持:
编辑 /etc/wsl.conf,确保包含:
[automount]<br>options = "metadata,uid=1000,gid=1000"
否则即使走 vscode.workspace.fs,文件属主和权限也可能在保存后重置。
切记不要在插件里调用 chmod +x —— NTFS 不支持执行位,该操作在 WSL 中仅临时生效,下次从 Windows 侧保存文件就会回退。
调试时路径授权不会自动继承,每次新路径都要重新触发
你在调试中调用 vscode.window.showOpenDialog(),用户选了 /home/user/docs/report.md,这时 VSCode 会自动为该 URI 授予读权限(因为 Uri[] 返回值自带授权上下文)。但如果你随后拼接出新路径:vscode.Uri.file('/home/user/docs/report.backup.md'),这个新 URI 并不继承授权 —— 它会被拒绝。
解决方式只有两种:
- 用
vscode.window.showSaveDialog({ defaultUri: originalUri })让用户再次确认目标路径(推荐,符合最小权限原则) - 捕获
OperationNotSupportedError,然后主动调用vscode.workspace.fs.createFileSystemWatcher()或其他需要权限的 API 触发授权弹窗(副作用是弹窗内容可能不直观)
硬编码路径 + 直接调用 vscode.workspace.fs 在调试阶段看似可行(比如你本地测试用固定路径),但上线后必然失败 —— 因为生产环境路径不可控,且用户不会为你预授权。
vscode.env.appRoot 可读,但不是你的“免检通道”
vscode.env.appRoot 指向 VSCode 安装目录(如 /usr/share/code 或 C:UsersXAppDataLocalProgramsMicrosoft VS Code),这个路径默认可读,不需要额外声明能力或触发授权。但它不能帮你绕过权限模型。
例如,你想读取 vscode.Uri.file(path.join(vscode.env.appRoot, '../extensions/my-ext/data.json')) —— 这个拼接路径依然属于外部文件系统路径,仍需声明 "workspace": { "read": true } 并获得对应路径授权。
真正容易被忽略的是:插件能访问 appRoot,不等于它能访问任何子路径;用户点了“允许”,也不代表子路径自动继承。这是 VSCode 权限模型的设计前提:按路径粒度控制,不信任任何隐式推导。











