Codex 在 Windows + PowerShell 上的问题,我们决定换个思路绕开
标题备选(数字钩子,需带上查询语句与日期): 「4,269 条 issue 标题里带 Windows:Codex 在 PowerShell 下的问题是结构性的」 「Codex CLI 有 203 条标题含 PowerShell 的 issue,我们不再指望修好它」 先说结论:Codex 在 Windows 上不是不能用,而是你把任务规模化之后,被 PowerShell 打断的次数会变成一种固定成本。我们试过的方向里,性价比最高
标题备选(数字钩子,需带上查询语句与日期):
- 「4,269 条 issue 标题里带 Windows:Codex 在 PowerShell 下的问题是结构性的」
- 「Codex CLI 有 203 条标题含 PowerShell 的 issue,我们不再指望修好它」
先说结论:Codex 在 Windows 上不是不能用,而是你把任务规模化之后,被 PowerShell 打断的次数会变成一种固定成本。我们试过的方向里,性价比最高的不是写更长的提示词教模型写 PowerShell,而是把执行面换到 Linux 用户态。
这篇先把网上能查到的真实问题摊开(都带链接,可以自己核),再讲我们在 TaskHandoff 里选的那条路,以及这条路的代价。
一、先看真实问题:四类,且不是同一类
A 类:PowerShell 不是 Bash,模型的命令会持续撞墙
- Codex CLI 在 PowerShell 下会反复生成
rg 'pattern' *.md这种写法,直接报os error 123;同一环境里rg -g '*.md' 'pattern' .是正常的。报告者的原话是:这不是一次失败,而是在正常使用中不断生成不被支持的命令形式,产生可避免的失败调用和恢复工作,浪费时间和 token(#45685)。 - 过大的 PowerShell 命令会在启动前就失败,报
os error 206(#45788)。 - 引号、反斜杠、JSON 参数被 PowerShell 改写;从 Bash 教程抄来的命令直接失败;
ExecutionPolicy拦截脚本;路径带空格或中文就出问题(knightli.com 的排查手册)。
B 类:Windows 特有的策略与沙箱层
-
exec_command在 PowerShell 还没启动前就被拒绝:CreateProcess rejected: blocked by policy,没有子进程 PID、没有退出码。值得注意的是,报告者当时已经配置approval_policy=Never+sandbox_policy=DangerFullAccess,依然被拦,而且错误信息不告诉你是哪一层策略拦的(#44839)。同类报告还有只读Get-Content被拒(#43881)、只读健康检查被拒(#43633)。 - Windows 沙箱阻塞 Node 子进程:
spawnSync EPERM、errno -4048;想改成提权模式,反而在 UAC 提示出现前就失败:helper_sandbox_lock_failed/SetNamedSecurityInfoW ... failed: 5(#45697)。同类还有子进程管道建立失败、PID 为 0(#44838)。
C 类:跨文件系统与路径映射
- 切到 WSL2 之后,项目路径会变成
/mnt/c/Program Files/WindowsApps/...这种形态;合法符号链接被拒;粘贴的图片 image tool 读不到(而沙箱里的 Bash 明明能读)(#44182)。Windows + WSL2 无法创建本地项目也有人在报(#45887)。 - CRLF 会让 Git 显示「所有文件都被修改」,权限位全部变化;同一个仓库可能出现 Windows 侧能拉取、WSL 侧不能拉取(knightli.com)。
- 官方说明里有一条容易被忽略:集成终端 shell 和 agent environment 是两个独立设置。你把集成终端改成 Git Bash,agent 依然用 PowerShell 跑命令(nenufm.com)。
D 类:安全软件与企业环境
- 卡巴斯基把
%USERPROFILE%\.codex\.sandbox-bin\codex-command-runner-0.154.0.exe判为PDM:Exploit.Win32.Generic.nblk并拦截;而该文件与官方 npm 包内的文件 SHA-256 完全一致,Kaspersky 自己的动态分析结果又是 Clean(#45810)。 - 与 FSLogix 不兼容(#45897);应用商店更新后启动失败报
rename_staging EPERM(#45858)。
规模参考(2026-09-16 用 GitHub 搜索查询,计数为近似值):repo:openai/codex type:issue 共 28,341 条,其中 label:"windows-os" 7,291 条,标题含 Windows 的 issue 4,269 条,标题含 PowerShell 的 203 条。
二、为什么「修好 PowerShell」这条路收益有限
把上面四类分开看就清楚了:A 类是 shell 语义差异,B 类是 Windows 安全模型与沙箱实现,C 类是跨文件系统映射,D 类是第三方安全软件。它们不是一个补丁能一起解决的问题。
社区里有人做过一轮很扎实的尝试(nenufm.com,2026-07-21 发布、2026-09-06 更新):
- 装了 PowerShell 7,对体验有帮助,保留;
- 把一大段 PowerShell 工具提示词放进全局
AGENTS.md——没解决问题,后来删掉了; - 装了 Coreutils 想让命令更接近 Unix,结果
PSConsoleHostReadLine会改写交互输入,Get-Command rm显示的别名和实际执行入口不一致,辨认成本上升,最后卸载; - 还发现失败未必跟 shell 语法有关:有一次是 Codex 调用了旧版本目录里的
codex.exe,换到当前安装路径就成功了——这种错误升级 PowerShell 或换 Bash 都救不了。
他最后的做法是把约束写简单:精确搜索用 rg -n -F、多条件用多个 -e、不要额外嵌套 pwsh -Command。
这条经验值得记住:提示词能降低概率,但降不到零;而每次失败的代价是一次工具调用、一次恢复、以及被消耗掉的上下文。
三、我们选的路:Windows 只当入口,任务跑在 Linux 侧
TaskHandoff 在 Windows 桌面端上有一个明确的约束:Windows 上创建本机实例走的是 Docker Runtime,内置 Local Runtime 只在受支持的非 Windows 节点提供(见 安装与登录)。
翻译成使用方式就是:Windows 负责界面,任务实际跑在 Linux 容器里。A 类的 PowerShell 语义问题、B 类的 Windows 沙箱策略问题,在这一层就不存在了——agent 执行的是容器内 Linux shell 的命令。
另外两条路径也在同一套模型里:
- 把远程 Linux 主机加为节点。 一台 Debian/Ubuntu 机器加入后,和本机实例出现在同一个控制面里,可以按节点、项目、状态筛选。装法和步骤见首次配置和远程节点。
- 只让 Windows 承担操作入口。 桌面端、浏览器、移动端、聊天桥接共用同一个控制面,跟进任务不需要守在一个 PowerShell 窗口前。
顺带解决掉几个 C 类和运维层面的老问题:
- 路径与工作目录:一次 AI 会话绑定固定工作目录,创建后不会自动改变;要换 worktree,就在目标 worktree 上新建会话(见使用 AI 会话)。少一层「Windows 路径 → WSL 路径 → 容器路径」的心智转换。
- 交付:改动通过文件/变更视图审阅,走分支或 worktree 交付;远端操作是保守的——Pull 仅允许 fast-forward,永远不 force push,分支分叉就阻止自动同步(见仓库协作)。
- 凭据:Git 凭据按「协议 + 主机 + 端口 + 大小写敏感的路径前缀」限定范围,不支持通配符;HTTPS token 只在 credential-helper 请求期间短暂提供,不写进 remote URL、命令行和环境变量(见Git 凭据)。不用在 Windows 上给每个项目单独配一遍。
- 长任务不靠窗口活着:关闭桌面主窗口只是隐藏到托盘,Docker Runtime 实例保持运行,下次启动后节点代理会重新发现并接管(见安装与登录)。配合移动端和聊天桥接,离开电脑也能看进度。
四、代价,说清楚
- Windows 上要装 Docker。 安装桌面应用本身不等于安装 Docker;创建 Docker 实例前,节点必须已安装并启动 Docker daemon,且当前用户有权限访问它。
- Local Runtime 在 Windows 上不可用,想要「直接使用宿主机目录和工具」的用法得放到非 Windows 节点上。
- 换成 Linux 用户态意味着接受 Linux 工具链。如果你的项目强依赖 Windows 专有工具,这套方式不适用。
- 多了一层容器:镜像拉取、卷管理和环境模板这些概念需要理解一次。
五、可复用的五条原则
- 区分「操作环境」和「执行环境」。 你人在 Windows 上工作,不代表 agent 必须在 PowerShell 里执行命令。
- 不要在提示词层面解决平台语义问题。 提示词能降低概率,不能替代把环境换对。
- 同一类问题要分层归因:shell 语义、沙箱策略、文件系统映射、安全软件——它们的解法完全不同。
- 让失败可解释。 「blocked by policy」这种没有规则归属的错误,会让 agent 和人都无法自行恢复;选工具时要把它算作一个真实成本。
- 长任务的存活不要依赖终端窗口。 判定方法:关掉窗口、重启界面服务,任务还在不在跑。
相关文档
- 安装与平台支持(含 Windows 使用 Docker Runtime 的说明):https://docs.thandoff.com/guide/install
- 首次配置:节点、环境、模型 Provider:https://docs.thandoff.com/guide/first-setup
- 远程节点接入:https://docs.thandoff.com/integrations/remote-nodes
- 会话与工作目录:https://docs.thandoff.com/sessions/
- 仓库协作与交付:https://docs.thandoff.com/workspace/repository
- Git 凭据范围管理:https://docs.thandoff.com/security/git-credentials
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.