Windows 下 ChatGPT / Codex Desktop 进程存在但没有窗口:cua_node Runtime Staging 异常排查与修复

问题现象

在 Windows 上启动 ChatGPT / Codex Desktop 后,任务管理器中可以看到多个 ChatGPT.exe 进程,进程状态也是正常响应,但桌面上始终没有任何可见窗口。

典型现象包括:

  • ChatGPT.exe 进程存在;
  • Responding = True
  • MainWindowHandle = 0
  • MainWindowTitle 为空;
  • 反复启动后仍没有窗口;
  • %LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node 下不断出现新的 .staging-* 目录;
  • .staging-* 目录中有 bin\node.exe,但缺少 bin\node_repl.exe

这种情况下,通常不是“窗口跑到屏幕外”这么简单,而是应用的 cua_node Runtime 没有正确完成 staging / relocation,导致 Renderer 或后续运行组件没有正常拉起。

本文记录的是一种已经在 OpenAI Codex GitHub Issues 中出现过的 Windows 故障模式及对应 workaround。它不是通用的“所有无窗口问题”解决办法,执行前应先按本文步骤确认症状一致。


一、确认是不是同一种问题

1. 检查 ChatGPT 进程窗口句柄

打开 PowerShell:

Get-Process ChatGPT -ErrorAction SilentlyContinue |
Select-Object Id, ProcessName, Responding, MainWindowHandle, MainWindowTitle, Path

如果结果类似:

Id               : 20500
ProcessName      : ChatGPT
Responding       : True
MainWindowHandle : 0
MainWindowTitle  :
Path             : C:\Program Files\WindowsApps\OpenAI.Codex_...\app\ChatGPT.exe

并且多个 ChatGPT.exe 都是:

Responding       : True
MainWindowHandle : 0

说明应用进程已经启动,但没有创建正常的可见主窗口。


2. 检查 AppX / MSIX 包状态

执行:

Get-AppxPackage -Name OpenAI.Codex |
Select-Object Name, Version, Status, PackageFullName, InstallLocation

正常情况下可以看到:

Name            : OpenAI.Codex
Version         : ...
Status          : Ok
PackageFullName : OpenAI.Codex_...
InstallLocation : C:\Program Files\WindowsApps\OpenAI.Codex_...

如果 Status = Ok,说明 Microsoft Store / MSIX 包本身至少处于已注册状态。

这时问题更可能发生在应用首次启动时复制到用户目录的 Runtime 阶段,而不是整个 AppX 包完全损坏。


二、检查 cua_node Runtime

执行:

Get-ChildItem "$env:LOCALAPPDATA\OpenAI\Codex\runtimes\cua_node" `
    -Directory -Force -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending |
Select-Object Name, LastWriteTime

如果看到大量类似:

.staging-e7fe122ad3cbcd58-HO2fM7
.staging-e7fe122ad3cbcd58-8O5cJZ
.staging-e7fe122ad3cbcd58-ZKHott
.staging-e7fe122ad3cbcd58-YL49vz
...

说明应用每次启动都在尝试准备 Runtime,但 staging 目录一直没有正常完成。

正常情况下,最终应该形成一个不带 .staging- 前缀的正式 Runtime 目录,例如:

e7fe122ad3cbcd58

三、检查 staging 目录是否不完整

执行:

$dir = Get-ChildItem "$env:LOCALAPPDATA\OpenAI\Codex\runtimes\cua_node" `
    -Directory -Force |
    Sort-Object LastWriteTime -Descending |
    Select-Object -First 1

$dir.FullName

Test-Path "$($dir.FullName)\bin\node.exe"
Test-Path "$($dir.FullName)\bin\node_repl.exe"

(Get-ChildItem $dir.FullName -Recurse -File -Force -ErrorAction SilentlyContinue).Count

如果结果类似:

node.exe       -> True
node_repl.exe  -> False

而且文件数量明显少于安装包中完整的 cua_node Runtime,那么基本可以判断 staging 没有完成。

这个问题已经在多个 Windows Codex Desktop Issue 中出现过:应用包里的完整 Runtime 是存在的,但复制到 %LOCALAPPDATA% 时中途失败,结果就是进程存在、没有 Renderer、没有主窗口。


四、先检查安装包中的 Runtime 是否完整

不要直接修改 C:\Program Files\WindowsApps 的权限,也不要去取得整个 WindowsApps 目录的所有权。

先让 PowerShell自动获取安装路径:

$pkg = Get-AppxPackage -Name OpenAI.Codex

$src = Join-Path $pkg.InstallLocation "app\resources\cua_node"

$src

然后检查关键文件:

Test-Path "$src\bin\node.exe"
Test-Path "$src\bin\node_repl.exe"
Test-Path "$src\manifest.json"

理想结果:

True
True
True

如果安装包本身的 node_repl.exe 也不存在,那么不要继续使用下面的手工 Runtime 恢复方案,应优先处理安装包本身的问题。


五、不卸载、不重置的 Runtime 修复方法

1. 先结束所有 ChatGPT 进程

Get-Process ChatGPT -ErrorAction SilentlyContinue | Stop-Process -Force

2. 自动识别 Runtime ID

执行:

$pkg = Get-AppxPackage -Name OpenAI.Codex

$src = Join-Path $pkg.InstallLocation "app\resources\cua_node"

$root = Join-Path $env:LOCALAPPDATA "OpenAI\Codex\runtimes\cua_node"

$staging = Get-ChildItem $root -Directory -Force |
    Where-Object { $_.Name -like ".staging-*" } |
    Sort-Object LastWriteTime -Descending |
    Select-Object -First 1

if (-not $staging) {
    throw "没有找到 cua_node 的 .staging-* 目录"
}

if ($staging.Name -notmatch '^\.staging-([^-]+)-') {
    throw "无法从 staging 目录名解析 runtime id:$($staging.Name)"
}

$runtimeId = $Matches[1]

$dst = Join-Path $root $runtimeId

Write-Host "安装包 Runtime:" $src
Write-Host "Runtime ID:" $runtimeId
Write-Host "目标目录:" $dst

例如:

.staging-e7fe122ad3cbcd58-HO2fM7

会解析出:

Runtime ID = e7fe122ad3cbcd58

最终正式 Runtime 目录应该是:

%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\e7fe122ad3cbcd58

3. 创建正式 Runtime 目录

New-Item -ItemType Directory -Force -Path $dst | Out-Null

4. 使用 xcopy /G 复制完整 Runtime

执行:

& "$env:SystemRoot\System32\xcopy.exe" `
    "$src" `
    "$dst\" `
    /E /I /H /Y /G

参数含义:

/E   复制所有子目录,包括空目录
/I   目标不存在时按目录处理
/H   包含隐藏文件和系统文件
/Y   覆盖时不反复询问
/G   允许将加密文件复制到不支持加密的目标

这里的 /G 很重要。

相关 GitHub Issue 中,这类故障与 WindowsApps / Application Protected 文件在 Runtime relocation 过程中的复制异常有关,xcopy /G 是已经有人验证可用的一种 workaround。


六、验证 Runtime 是否完整

复制完成后执行:

Write-Host "node.exe:"
Test-Path "$dst\bin\node.exe"

Write-Host "node_repl.exe:"
Test-Path "$dst\bin\node_repl.exe"

Write-Host "manifest.json:"
Test-Path "$dst\manifest.json"

Write-Host "文件总数:"
(Get-ChildItem $dst -Recurse -File -Force).Count

至少应确认:

node.exe:
True

node_repl.exe:
True

manifest.json:
True

如果 node_repl.exe 仍然是 False,说明复制没有成功,不建议继续反复启动应用。


七、重新启动 ChatGPT / Codex Desktop

建议从:

Windows 开始菜单

重新启动应用。

不要直接进入:

C:\Program Files\WindowsApps\...

双击内部 ChatGPT.exe

启动后检查:

Get-CimInstance Win32_Process -Filter "Name='ChatGPT.exe'" |
Select-Object ProcessId, CommandLine

正常情况下应该能看到 Renderer 进程,例如命令行中包含:

--type=renderer

再执行:

Get-Process ChatGPT |
Select-Object Id, MainWindowHandle, MainWindowTitle

修复成功后,不应该再是所有进程:

MainWindowHandle = 0

通常会有一个主进程拥有非 0 的窗口句柄。


八、为什么简单“移动窗口”没有用

如果只是窗口跑到了屏幕外,可以尝试:

Alt + Space
Win + Shift + ←
Win + Shift + →

但是在本文这种故障中:

ChatGPT.exe 存在
MainWindowHandle = 0
Renderer 未启动

意味着应用根本没有正常创建可见窗口。

因此:

移动窗口
最大化窗口
切换显示器

都无法解决根本问题。


九、为什么不建议直接修改 WindowsApps 权限

C:\Program Files\WindowsApps 是 Microsoft Store / MSIX 应用的受保护安装目录。

不建议为了复制一个文件而:

取得整个 WindowsApps 的所有权
给 Everyone 完全控制
修改整个目录 ACL
手动覆盖应用文件

这样可能影响:

  • Store 应用更新;
  • MSIX 包完整性;
  • 应用启动;
  • 后续版本升级。

本文的思路是:

安装包目录只读
        ↓
读取官方打包的 cua_node
        ↓
复制到当前用户自己的 Runtime 目录

不直接修改安装包。


十、完整的一键检查脚本

下面这段只负责检查,不执行复制:

$pkg = Get-AppxPackage -Name OpenAI.Codex

if (-not $pkg) {
    Write-Host "没有找到 OpenAI.Codex AppX 包"
    return
}

Write-Host "========== AppX =========="
$pkg | Select-Object Name, Version, Status, PackageFullName, InstallLocation

$src = Join-Path $pkg.InstallLocation "app\resources\cua_node"
$root = Join-Path $env:LOCALAPPDATA "OpenAI\Codex\runtimes\cua_node"

Write-Host ""
Write-Host "========== 安装包 Runtime =========="
Write-Host "路径:" $src
Write-Host "node.exe:" (Test-Path "$src\bin\node.exe")
Write-Host "node_repl.exe:" (Test-Path "$src\bin\node_repl.exe")
Write-Host "manifest.json:" (Test-Path "$src\manifest.json")

Write-Host ""
Write-Host "========== 本地 staging =========="

$staging = Get-ChildItem $root -Directory -Force -ErrorAction SilentlyContinue |
    Where-Object { $_.Name -like ".staging-*" } |
    Sort-Object LastWriteTime -Descending

$staging |
    Select-Object Name, LastWriteTime

if ($staging) {

    $latest = $staging | Select-Object -First 1

    Write-Host ""
    Write-Host "最新 staging:" $latest.FullName
    Write-Host "node.exe:" (Test-Path "$($latest.FullName)\bin\node.exe")
    Write-Host "node_repl.exe:" (Test-Path "$($latest.FullName)\bin\node_repl.exe")
    Write-Host "manifest.json:" (Test-Path "$($latest.FullName)\manifest.json")

    Write-Host "文件数:" (
        Get-ChildItem $latest.FullName -Recurse -File -Force -ErrorAction SilentlyContinue
    ).Count
}

Write-Host ""
Write-Host "========== ChatGPT 进程 =========="

Get-Process ChatGPT -ErrorAction SilentlyContinue |
    Select-Object Id, ProcessName, Responding, MainWindowHandle, MainWindowTitle, Path

十一、完整的一键恢复脚本

建议先执行上一节的检查脚本,确认问题确实是 cua_node staging 不完整,再执行恢复脚本。

$ErrorActionPreference = "Stop"

Write-Host "1. 获取 OpenAI.Codex AppX 包..."

$pkg = Get-AppxPackage -Name OpenAI.Codex

if (-not $pkg) {
    throw "没有找到 OpenAI.Codex AppX 包"
}

$src = Join-Path $pkg.InstallLocation "app\resources\cua_node"
$root = Join-Path $env:LOCALAPPDATA "OpenAI\Codex\runtimes\cua_node"

Write-Host "安装包 Runtime:" $src

if (-not (Test-Path "$src\bin\node.exe")) {
    throw "安装包中缺少 bin\node.exe"
}

if (-not (Test-Path "$src\bin\node_repl.exe")) {
    throw "安装包中缺少 bin\node_repl.exe"
}

if (-not (Test-Path "$src\manifest.json")) {
    throw "安装包中缺少 manifest.json"
}

Write-Host ""
Write-Host "2. 查找最新 staging..."

$staging = Get-ChildItem $root -Directory -Force |
    Where-Object { $_.Name -like ".staging-*" } |
    Sort-Object LastWriteTime -Descending |
    Select-Object -First 1

if (-not $staging) {
    throw "没有找到 cua_node 的 .staging-* 目录"
}

Write-Host "最新 staging:" $staging.FullName

if ($staging.Name -notmatch '^\.staging-([^-]+)-') {
    throw "无法解析 Runtime ID:$($staging.Name)"
}

$runtimeId = $Matches[1]
$dst = Join-Path $root $runtimeId

Write-Host "Runtime ID:" $runtimeId
Write-Host "目标 Runtime:" $dst

Write-Host ""
Write-Host "3. 结束 ChatGPT 进程..."

Get-Process ChatGPT -ErrorAction SilentlyContinue |
    Stop-Process -Force

Start-Sleep -Seconds 2

Write-Host ""
Write-Host "4. 创建 Runtime 目录..."

New-Item -ItemType Directory -Force -Path $dst |
    Out-Null

Write-Host ""
Write-Host "5. 复制完整 cua_node Runtime..."

& "$env:SystemRoot\System32\xcopy.exe" `
    "$src" `
    "$dst\" `
    /E /I /H /Y /G

if ($LASTEXITCODE -gt 1) {
    throw "xcopy 执行失败,ExitCode=$LASTEXITCODE"
}

Write-Host ""
Write-Host "6. 验证关键文件..."

$nodeOk = Test-Path "$dst\bin\node.exe"
$replOk = Test-Path "$dst\bin\node_repl.exe"
$manifestOk = Test-Path "$dst\manifest.json"

Write-Host "node.exe:" $nodeOk
Write-Host "node_repl.exe:" $replOk
Write-Host "manifest.json:" $manifestOk

$fileCount = (
    Get-ChildItem $dst -Recurse -File -Force -ErrorAction SilentlyContinue
).Count

Write-Host "文件总数:" $fileCount

if (-not $nodeOk -or -not $replOk -or -not $manifestOk) {
    throw "Runtime 仍不完整,请不要继续启动应用"
}

Write-Host ""
Write-Host "Runtime 恢复完成。"
Write-Host "现在请从 Windows 开始菜单重新启动 ChatGPT / Codex Desktop。"

十二、注意事项

1. 不要删除旧 staging 目录作为第一步

大量 .staging-* 是故障现象,但直接删除它们不一定能解决根因。

应用下一次启动仍可能重新创建新的不完整 staging。

因此更重要的是先确认:

安装包 Runtime 是否完整
正式 Runtime 是否完整
node_repl.exe 是否存在

2. 不建议只复制 node_repl.exe

有些版本中不只是 node_repl.exe 一个文件缺失,整个 staging 目录都可能是不完整的。

所以更稳妥的 workaround 是:

复制完整 cua_node Runtime

而不是只补一个 EXE。


3. 版本升级后可能再次变化

Runtime ID 与应用版本有关。

例如:

e7fe122ad3cbcd58

只是某个版本对应的内容 ID。

不要把 Runtime ID 永久硬编码在脚本里,应从最新:

.staging-<runtime-id>-<random>

动态解析。


十三、排查逻辑总结

整个问题可以简化成:

启动 ChatGPT / Codex Desktop
          ↓
ChatGPT.exe 进程存在
          ↓
MainWindowHandle = 0
          ↓
检查 Renderer
          ↓
Renderer 未正常出现
          ↓
检查 cua_node
          ↓
不断生成 .staging-* 目录
          ↓
node.exe 存在
node_repl.exe 缺失
          ↓
Runtime staging / relocation 未完成
          ↓
从 MSIX 安装包复制完整 cua_node
          ↓
生成正式 Runtime 目录
          ↓
重新启动
          ↓
Renderer 正常启动
          ↓
桌面窗口恢复

十四、参考问题

截至 2026 年 9 月,OpenAI Codex GitHub Issues 中已经出现多起相近的 Windows 桌面端问题,例如:

  • [Windows] 26.901.1978.0 fails to launch UI when cua_node staging cannot copy node_repl.exe

    • https://github.com/openai/codex/issues/42501
  • Bug report: ChatGPT/Codex Desktop repeatedly fails to start on Windows after auto-update due to cua_node runtime relocation

    • https://github.com/openai/codex/issues/42412
  • [Windows] ChatGPT.exe remains running but no GUI appears — CUA Runtime staging/relocation anomaly observed

    • https://github.com/openai/codex/issues/42673
  • [Windows][26.825.5331.0] Headless startup caused by Application Protected node_repl.exe relocation failure

    • https://github.com/openai/codex/issues/41540

需要注意:这些 GitHub Issue 反映的是实际用户报告和已验证 workaround,不等同于官方正式发布的长期修复方案。后续版本可能已经修改 Runtime staging 逻辑,因此遇到新版本问题时仍应先检查当前版本的实际目录和日志。


结语

如果 Windows 下 ChatGPT / Codex Desktop 出现:

进程存在
Responding = True
MainWindowHandle = 0
没有窗口

不要第一时间卸载重装。

先检查:

%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node

如果发现:

不断出现 .staging-* 目录
node.exe 存在
node_repl.exe 缺失

那么问题很可能在 cua_node Runtime staging / relocation。

在确认安装包中的完整 Runtime 正常后,将完整 cua_node 复制到正确的正式 Runtime 目录,是目前一个可行且相对温和的修复办法。

Logo

AtomGit AI 社区提供模型库、数据集、Agent、Token等资源

更多推荐