日期:2026-07-30
环境:Windows 11、Codex Desktop、PowerShell 7.6.4、Windows 原生沙盒
关键词:Codex、Windows Sandbox、PowerShell、MSIX、CreateProcessAsUserW
背景
在 Windows 上使用 Codex Desktop 时,我发现任何需要调用 PowerShell 的普通沙盒命令都会在启动阶段失败。即使只是执行下面这种完全只读的命令,也无法运行:
Get-Location错误信息是:
windows sandbox: CreateProcessAsUserW failed: 5 (拒绝访问。)但同一条命令在获准使用非沙盒执行后可以正常运行。这说明问题不是 PowerShell 命令本身,而是发生在 Codex 创建沙盒进程的阶段。
这篇文章记录了从发现问题、走入 ACL 误区、构造对照实验,到最终通过更换 PowerShell 安装类型解决问题的完整过程。
最初的现象
第一次测试时,Codex 沙盒尝试启动的是:
C:\Users\<用户名>\AppData\Local\Microsoft\WindowsApps\pwsh.exe系统在 CreateProcessAsUserW 阶段直接返回错误 5:
CreateProcessAsUserW failed: 5对照测试的结果如下:
| 测试 | 结果 |
|---|---|
| 沙盒内执行 PowerShell | 失败 |
| 非沙盒执行 PowerShell | 成功 |
| 工作区文件写入工具 | 成功 |
| PowerShell 版本 | 7.6.4 |
| 工作目录 | 正确 |
初步可以判断:
- Codex 本身仍可工作;
- 工作区权限不是完全损坏;
- 故障集中在 Windows 沙盒创建 PowerShell 子进程的路径上。
第一个误区:怀疑 WindowsApps 别名 ACL
C:\Users\<用户名>\AppData\Local\Microsoft\WindowsApps\pwsh.exe 是一个 App Execution Alias,而不是普通可执行文件。检查发现,该文件最初只显式允许当前用户、管理员和 SYSTEM 访问,没有出现 CodexSandboxUsers。
当时很自然地怀疑:沙盒组是否因为缺少别名执行权限而被拒绝?
于是先后尝试给别名和父目录补充最小权限:
icacls "$env:LOCALAPPDATA\Microsoft\WindowsApps\pwsh.exe" `
/grant "1INXU\CodexSandboxUsers:(RX)"
icacls "$env:LOCALAPPDATA\Microsoft\WindowsApps" `
/grant "1INXU\CodexSandboxUsers:(X)"其中:
(RX)表示读取和执行;(X)对目录表示穿越/执行。
修改后重新启动 Codex,问题仍然存在。再次检查 ACL,确认权限确实已经写入,但 CreateProcessAsUserW 依旧返回拒绝访问。
这个结果证明:单纯修改别名 ACL 并不能解决问题。
为了避免留下没有必要的权限扩展,后续移除了这两条授权:
icacls "$env:LOCALAPPDATA\Microsoft\WindowsApps\pwsh.exe" `
/remove "1INXU\CodexSandboxUsers"
icacls "$env:LOCALAPPDATA\Microsoft\WindowsApps" `
/remove "1INXU\CodexSandboxUsers"这一步是整个排查过程里很重要的纠正:看到“拒绝访问”并不意味着一定要继续扩大 ACL。应先确定究竟是哪一类可执行文件、哪一种令牌和哪条启动路径产生了差异。
转折点:比较不同 Shell
真正定位问题的是一组控制变量实验。
我使用相同的 Codex 受限沙盒,分别启动:
cmd.exe- Windows PowerShell 5.1
- Microsoft Store/MSIX 版 PowerShell 7
测试 cmd.exe
codex sandbox -- cmd.exe /c echo CMD_SANDBOX_OK结果:
CMD_SANDBOX_OK测试 Windows PowerShell 5.1
codex sandbox -- `
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" `
-NoProfile `
-Command "'WINDOWS_POWERSHELL_SANDBOX_OK'"结果:
WINDOWS_POWERSHELL_SANDBOX_OK测试 Store/MSIX 版 PowerShell 7
codex sandbox -- `
"C:\Program Files\WindowsApps\Microsoft.PowerShell_7.6.4.0_x64__8wekyb3d8bbwe\pwsh.exe" `
-NoProfile `
-Command "'PWSH_SANDBOX_OK'"结果:
CreateProcessAsUserW failed: -1073283067这里的 -1073283067 对应十六进制 0xC0070005,低 16 位仍然是错误码 5,也就是 ERROR_ACCESS_DENIED。它不是另一种故障,只是 unelevated 沙盒后端没有正确解码和显示错误。
至此,问题范围已经非常清楚:
| Shell | 沙盒结果 |
|---|---|
cmd.exe | 成功 |
| Windows PowerShell 5.1 | 成功 |
| Store/MSIX PowerShell 7.6.4 | 失败 |
如果是工作区权限、Codex runner 或受限令牌整体损坏,cmd.exe 和 Windows PowerShell 5.1 也应该失败。但它们能够正常运行,说明问题具有明确的安装类型相关性。
互联网与 GitHub Issues 检索
随后检索 OpenAI 官方文档、Microsoft 文档和 openai/codex Issues,找到了与本机情况几乎完全一致的报告。
核心 Issue:#35871
openai/codex #35871 的标题就是:
Windows sandbox: CreateProcessAsUserW fails with error 5 when the resolved shell is the MSIX (Store) build of pwsh
该 Issue 在同一台机器、同一会话中对不同 Shell 各进行了 20 次测试:
| Shell | 失败次数 |
|---|---|
Store/MSIX pwsh.exe | 20/20 |
| Windows PowerShell 5.1 | 0/20 |
cmd.exe | 0/20 |
| Git Bash | 0/20 |
Issue 还确认:从交给 Codex 的 PATH 中移除 WindowsApps 路径后,Codex 会回退到 Windows PowerShell 5.1,并正常运行。
截至 2026-07-30,该 Issue 仍为 Open,带有 bug、sandbox、windows-os 等标签,尚无关联修复 PR。
错误码显示问题:#35958
openai/codex #35958 专门解释了:
-1073283067这个负数实际是包装后的 ERROR_ACCESS_DENIED。该 Issue 属于错误信息格式问题,底层启动失败仍由 #35871 跟踪。
其他相关但不同的故障
检索过程中还发现了:
- #26186:上层症状同样是
CreateProcessAsUserW failed: 5; - #32655:Codex helper 相对于 PATH shim 解析错误;
- #31101:错误 1920 和残留 runner 进程;
- #29072:Codex 沙盒 helper 从 WindowsApps 包路径启动失败。
不过,本次环境中 cmd.exe 能正常通过相同沙盒运行,Codex helper 也可以完成基础启动,因此 helper 丢失、runner 全局失效和工作区 ACL 损坏都不是主要原因。
为什么会安装到 MSIX 版本?
根据 Microsoft 的 PowerShell 7 安装文档,从 PowerShell 7.6.0 开始:
winget install --id Microsoft.PowerShell --source winget默认安装的是 MSIX 版本。
如果要安装传统 MSI 版本,必须显式指定:
winget install `
--id Microsoft.PowerShell `
--source winget `
--installer-type wixMSIX 版通常位于:
C:\Program Files\WindowsApps\Microsoft.PowerShell_...\pwsh.exeMSI 版则位于:
C:\Program Files\PowerShell\7\pwsh.exe这两个路径是判断 PowerShell 安装类型最直接的证据。
最终解决方案
1. 安装非 MSIX 的 PowerShell 7
使用官方建议的 WinGet 命令安装 MSI/WiX 版本:
winget install `
--id Microsoft.PowerShell `
--source winget `
--installer-type wix也可以从 Microsoft 文档链接到的 PowerShell GitHub Release 手动下载 x64 MSI。
2. 移除 Store/MSIX 版 PowerShell
在 Windows 的:
设置 → 应用 → 已安装的应用中卸载 Microsoft Store/MSIX 版 PowerShell,保留 MSI 版。
需要注意:这里卸载的是 PowerShell,不是 Codex Desktop。
3. 验证路径解析
where.exe pwsh期望首个结果为:
C:\Program Files\PowerShell\7\pwsh.exe不应该再解析到:
C:\Program Files\WindowsApps\...或:
C:\Users\<用户名>\AppData\Local\Microsoft\WindowsApps\pwsh.exe4. 完全重新启动 Codex
关闭 Codex Desktop,并确认相关后台进程已经结束,再重新打开应用,让新的 PATH 和 Shell 解析结果进入 Codex 运行环境。
修复后的完整验证
修复完成后,默认 PowerShell 检测结果为:
Version 7.6.4
Edition Core
Executable C:\Program Files\PowerShell\7\pwsh.exe随后重新验证各项沙盒边界。
工作区内写入、读取和清理
结果:
PASS: sandbox-workspace-ok工作区外写入
向允许根目录之外的现有目录写入探针文件,结果:
Access to the path ... is denied这说明沙盒没有因为排障而变成“全盘可写”。
网络隔离
沙盒中的直接网络请求被转发至本地拒绝端口并失败,说明网络限制仍然生效。
子进程
CMD_CHILD_OK
MSI_PWSH_CHILD_OK最终检查矩阵
| 检查项 | 结果 |
|---|---|
| 默认 PowerShell | 7.6.4 Core |
| 默认路径 | C:\Program Files\PowerShell\7\pwsh.exe |
| PowerShell 命令执行 | 正常 |
| PowerShell 子进程 | 正常 |
cmd.exe 子进程 | 正常 |
| 工作区内读写 | 正常 |
| 工作区外写入 | 正确阻止 |
| 直接网络访问 | 正确阻止 |
| 测试文件清理 | 无残留 |
CreateProcessAsUserW 错误 | 不再出现 |
Codex Desktop 本身是 MSIX,会不会也有问题?
这次故障来自 MSIX 版 PowerShell,而不是 Codex Desktop 本身。
根据 Codex/ChatGPT Windows 企业部署文档,当前 Windows 桌面 App 只有以下安装路径:
- Microsoft Store;
- 官方 Web Installer;
- 企业直接部署 Store 签名的 x64/Arm64 MSIX。
官方明确说明,目前不提供独立 MSI 或非 Store EXE 的桌面 App。
这并不影响本次修复。Codex Desktop 仍然使用官方 MSIX 包,只要它调用的是普通 MSI 版 PowerShell 7,Windows 原生沙盒就可以正常运行。
如果确实需要非 MSIX 的 Codex 运行方式,可以使用没有桌面 UI 的 Codex CLI 独立安装版:
irm https://chatgpt.com/codex/install.ps1 | iex但这不是解决本次故障的必要条件。
排障经验总结
1. Access denied 不等于应该继续放宽 ACL
权限错误可能来自:
- 文件 ACL;
- 目录穿越权限;
- 受限令牌;
- AppX/MSIX 激活模型;
- Windows 沙盒后端;
- Shell 解析到了错误的安装类型。
只有在对照实验确认 ACL 是变量时,才应该修改 ACL。
2. 比较不同可执行文件比反复重启更有效
本次最关键的证据不是重启或重装,而是:
cmd 成功
Windows PowerShell 5.1 成功
MSIX PowerShell 7 失败一组好的对照实验往往可以快速排除整个故障层级。
3. 必须检查实际可执行路径
仅看到“PowerShell 7.6.4”还不够。下面两个 PowerShell 7.6.4 的行为可能完全不同:
C:\Program Files\WindowsApps\...\pwsh.exe
C:\Program Files\PowerShell\7\pwsh.exe建议同时检查:
$PSVersionTable.PSVersion
(Get-Process -Id $PID).Path
(Get-Command pwsh).Source
where.exe pwsh4. WinGet 的默认安装类型可能发生变化
PowerShell 7.6.0 起,WinGet 默认选择 MSIX。只写包 ID 并不能保证得到 MSI:
winget install --id Microsoft.PowerShell --source winget需要 MSI 时,应明确指定:
--installer-type wix5. 修复后要验证安全边界没有被破坏
一个完整的修复验证不应只检查“命令能跑”,还应检查:
- 工作区内是否可以正常写入;
- 工作区外是否仍被阻止;
- 网络是否仍受限;
- 临时探针是否清理;
- 默认 Shell 是否指向预期路径。
结论
这次 CreateProcessAsUserW failed: 5 的根因是:
Codex Windows 沙盒解析到了 Microsoft Store/MSIX 版 PowerShell 7,而该可执行文件无法通过当前 Codex 受限令牌启动路径正常运行。
最终有效的解决方法是:
- 安装 MSI/WiX 版 PowerShell 7;
- 移除 Store/MSIX 版 PowerShell;
- 确认
pwsh指向C:\Program Files\PowerShell\7\pwsh.exe; - 完全重新启动 Codex;
- 验证命令执行与沙盒隔离边界。
修复后,PowerShell 7.6.4、工作区读写、子进程调用和网络/文件权限隔离全部恢复正常。