Codex 在 Windows 上最常见的问题,往往不是模型能力,而是运行环境:命令装在 Windows 还是 WSL、仓库在哪个文件系统、Git 用哪套凭据、终端继承了哪些变量、沙箱允许写到哪里。
原生 PowerShell 和 WSL 都能当入口。不要在同一次任务里混用两套 Node、Git、Python 和路径。
本文安装命令以 OpenAI Codex 文档 当前页为准;包名必须是 @openai/codex,npm 上未加作用域的 codex 是另一个项目。
先选一条路
原生 PowerShell 更适合:代码本来就在 C:\Work,依赖 Visual Studio / MSBuild / Windows SDK,测试必须调 Windows 程序,团队脚本以 PowerShell 为主。
WSL 更适合:生产环境是 Linux,依赖 Bash / GNU 工具 / Docker Linux 工作流,代码对大小写、权限位或符号链接敏感,README 主要是 Linux 命令。
原则很简单:让 Codex 和项目主工具链待在同一边。
先盘点两套环境
PowerShell:
Get-Command codex, node, git -ErrorAction SilentlyContinue
codex --version
node --version
git --version
(Get-Command codex).Source
npm config get prefix
再进 WSL:
wsl --status
wsl --list --verbose
command -v codex node git
which node npm codex
file "$(which codex)"
两边版本不同不是错误,它们本来就是独立环境。真正的坑是:你以为升级了一个,实际跑的是另一个。WSL 里 which codex 指向 .cmd,说明 PATH 混进了 Windows npm 全局目录——应在 WSL 内装 Linux 版,不要调用 /mnt/c/Program Files/nodejs/npm.cmd 假装完成 Linux 安装。
原生安装和登录
确认 64 位进程和 Node 可用后:
$PSVersionTable
[Environment]::Is64BitProcess
npm install -g @openai/codex
Get-Command codex
codex --version
codex login
用哪个用户登录,就用哪个用户跑。管理员 PowerShell 登录、普通用户运行,凭据目录可能对不上。临时 Key 只放当前进程:
$env:OPENAI_API_KEY = '<temporary-key>'
不要写进 Profile、仓库脚本或命令历史。环境变量改完要开新窗口才生效。
打开仓库用绝对路径:
Set-Location -LiteralPath 'C:\Work\my-project'
git rev-parse --show-toplevel
git status --short
codex
有空格或中文时,-LiteralPath 比手工转义稳。启动后先让它只读汇报工作目录和分支,路径必须和 git rev-parse --show-toplevel 一致。
WSL:仓库放 /home 还是 /mnt/c
Linux 工具链优先放 WSL 自己的盘,例如 ~/src。/mnt/c/... 方便 Visual Studio 直接打开,但大量小文件、权限位、符号链接、文件监听和大小写行为都可能和 Linux 原生盘不同。
必须两边共用时,先测:npm 安装速度、Git 权限位是否狂跳、Watcher 会不会漏、符号链接能不能建、测试是否依赖大小写。不要让 Windows 和 WSL 两个格式化器同时改同一棵树。
路径用 wslpath 转,不要手写替换:
wslpath 'C:\Work\my-project'
wslpath -w /home/user/src/project
C:\... 不要直接丢给 Linux 原生命令;/home/... 也不要指望普通 Windows 程序认。Codex 工具调用里的路径,必须属于启动它的那套环境。
Git、换行、引号
PowerShell 的 Git 常用 Git Credential Manager;WSL 可能是 SSH Agent、Linux store,或什么都没配。一边能 git pull、一边不行,多半是凭据,不是 Codex。不要把 PAT 写进 remote URL。
Windows 默认 CRLF,Linux 默认 LF。.gitattributes 没写清楚,跨环境一切换,Git 会以为整库都改了:
* text=auto
*.sh text eol=lf
*.ps1 text eol=crlf
规则跟团队走。Agent 刚启动就看到几百个变化,先停手,分清是换行、权限位还是生成文件。权限位全变时看 core.fileMode 和仓库是否在 /mnt/c,不要直接提交。
PowerShell 单引号不展开变量,双引号会。JSON、正则里的 $、带空格的路径、Git 提交信息里的反引号,都容易被拆坏。旧版 Windows PowerShell 里 curl 可能是 Invoke-WebRequest 的别名。写命令时说清楚「在 PowerShell 7 里跑」,不要只说「Windows 命令」。从 Bash 教程复制的 export、VAR=value cmd、管道进 bash,都不能原样贴进 PowerShell。
沙箱不是 UAC
Codex 沙箱管这次 Agent 能读、写、执行什么;UAC 和 NTFS ACL 管操作系统权限。管理员跑着,沙箱仍可能拒写;沙箱放行了,也突破不了 NTFS。
Access denied 要分层看:沙箱范围、NTFS ACL、只读属性、杀毒拦截、文件锁、路径过长、WSL 挂载权限映射。不要为了少点一次批准就开最高权限,更不要给整个盘 Everyone Full Control。
外部程序看 $LASTEXITCODE;Copy-Item 这类 cmdlet 看终止错误,两者不要混。
其他常见坑
Node / Python 多套: winget、nvm-windows、Volta、WSL nvm 可以同时存在。让 Agent 装依赖前先看 packageManager、锁文件、.nvmrc。同时出现多种 lockfile 时,别让它猜。
Docker: PowerShell 和 WSL 都可能连 Docker Desktop,上下文和 bind mount 路径不同。Compose 里 Windows 路径、WSL 路径和 named volume 不能随便换。能访问 Docker daemon 通常等于能拿到宿主机高权限。
代理: 浏览器能登录,不代表 npm / Git / Codex CLI 都能出网。WSL 环境变量不自动跟 Windows 同步。不要靠关 TLS 校验过日子。
执行策略: running scripts is disabled 是 PowerShell 策略,不是模型坏了。只跑 codex 通常不用改;.ps1 才需要 RemoteSigned 或一次性 Bypass。
任务开始前留下基线:git status、当前分支、仓库根。结束用 git diff 和项目测试验收,不要用「Codex 说完成了」代替。
一套比较稳的组合
- Windows / .NET / PowerShell 项目:代码在 NTFS,原生 Codex + Windows Git + PowerShell 7(
pwsh.exe,不是自带的 5.1)。 - Linux 服务 / Node / Python:代码在 WSL
~/src,WSL Codex + Linux Git + Bash。 - 必须跨两边:指定唯一的 Git 写入环境,另一边只跑特定工具,
.gitattributes钉死换行。
最重要的不是哪条路线更高级,而是命令、文件系统、凭据和测试能不能解释成同一套环境。环境稳了,排错成本会明显下降。