ChatGPT Windows 客户端点击无反应、有进程却没窗口?一次 MSIX 非系统盘启动卡死的完整排查

摘要:如果你的 ChatGPT Windows 客户端安装在 D 盘,更新后突然出现点击图标没反应、任务管理器里有进程、CPU 占用较高但始终没有窗口,可以尝试把应用移动到 C 盘。

本文不只提供解决方法,还会结合 Windows 事件日志、应用日志、残留文件和客户端代码,分析它为什么有效。

一、故障现象

这次问题出现在 Microsoft Store 版本的 ChatGPT Windows 客户端上。

故障表现包括:

  • 点击 ChatGPT 图标没有任何窗口;
  • 任务管理器中能看到多个 ChatGPT.exe 进程;
  • 主进程没有窗口句柄;
  • 某个 CPU 线程持续高占用;
  • 等待很久也没有进入登录界面或主界面;
  • 重启电脑、结束进程、卸载重装后仍可能复现;
  • 在 Windows 设置中把 ChatGPT 移动到 C 盘后,应用立即恢复。

如果你的现象与这些特征基本一致,本文的解决方法很可能适用。

不过需要强调:并不是所有ChatGPT 无法启动都由这个问题引起。如果应用原本就在 C 盘,或者日志中没有运行时暂存痕迹,还需要继续排查显卡、权限、配置文件或应用数据损坏等其他原因。

二、先说解决方法

推荐方法:把 ChatGPT 移动到 C 盘

打开 Windows 设置:

text 复制代码
设置
→ 应用
→ 已安装的应用
→ ChatGPT
→ 移动
→ 选择 C 盘

不同 Windows 版本的入口可能略有差异,移动按钮也可能位于三点菜单或高级选项中。

移动完成后,重新打开 ChatGPT,然后就可以看到ChatGPT的页面了。

在本次故障中,同一个应用版本移动到 C 盘后,不需要清除数据或重新登录,窗口就恢复了。

备用方案:没有移动按钮时

可以先修改 Microsoft Store 新应用的默认安装位置:

text 复制代码
设置
→ 系统
→ 存储
→ 高级存储设置
→ 新内容的保存位置
→ 新应用将保存到 C 盘

然后重新安装 ChatGPT。

卸载应用可能会清理一部分本地缓存和应用状态,因此操作前最好备份重要的本地内容。

不要手动移动 WindowsApps 文件夹,也不要随意修改它的所有者和访问权限。这可能破坏 Microsoft Store 的更新和完整性校验。

三、最初的判断:是不是文件在 C、注册在 D?

刚开始排查时,一个很容易出现的判断是:

应用注册在 D 盘,但更新后的文件被装到了 C:\Program Files\WindowsApps,因此形成了跨盘分裂状态。

后来通过 Windows 事件日志确认,这个结论并不正确。

AppX 部署日志显示,出现问题的两个版本都明确部署到了 D 盘:

text 复制代码
OpenAI.Codex_26.825.4187.0
Target volume: D:

OpenAI.Codex_26.825.6671.0
Target volume: D:

Windows Error Reporting 记录的实际可执行文件路径也是:

text 复制代码
D:\WindowsApps\OpenAI.Codex_26.825.6671.0_x64__...\app\ChatGPT.exe

因此,更新后的文件并没有偷偷跑到 C 盘。

之所以某些查询结果会显示:

text 复制代码
C:\Program Files\WindowsApps\OpenAI.Codex_...

是因为 Windows 会为非系统盘上的 AppX/MSIX 包建立逻辑入口或目录联接。表面路径可能位于 C 盘,物理文件实际上仍然位于 D 盘。

Microsoft 官方也说明,PackageVolume 不只可以位于 C 盘,也可以建立在其他驱动器上:Understanding how packaged desktop apps run on Windows

所以,真正的问题并不是注册和文件分裂。

四、真正卡住的步骤:搬运 cua_node 运行时

ChatGPT 当前的 Windows 包中包含一个名为 cua_node 的运行时,里面包括:

  • node.exe;
  • node_repl.exe;
  • npm 相关文件;
  • Playwright;
  • OCR、图像和浏览器自动化相关依赖;
  • 大量 node_modules。

在本次版本中,这个目录大约包含:

text 复制代码
文件数量:4680
总大小:318.88 MiB

应用启动时不会直接从受保护的 WindowsApps 目录使用这些文件,而是要把它们复制到用户目录:

text 复制代码
%LOCALAPPDATA%\OpenAI\Codex\runtimes\cua_node\

复制过程中会先建立类似下面的临时目录:

text 复制代码
.staging-e4d75eceaa042f20-HCFkgX
.staging-e4d75eceaa042f20-naQjRk
.staging-e4d75eceaa042f20-8iFoyJ

全部复制完成后,暂存目录才会被重命名为正式运行时目录。

问题就发生在这个过程里。

五、本地留下了大量未完成的暂存目录

排查时,在本地发现了:

text 复制代码
失败的 .staging-* 目录:21 个
残留文件:23832 个
占用空间:约 3.78 GiB

这些目录都没有最终的 manifest.json,说明运行时复制从未正常完成。

几个典型启动过程如下:

启动时间 暂存目录最后写入 进程结束 已复制数据
10:22:20 10:36:13.775 10:36:14.094 257.05 MiB
10:46:30 10:58:45.949 10:58:46.225 262.65 MiB
11:02:09 11:13:37.231 11:13:37.895 239.06 MiB

暂存文件停止写入的时间与应用进程结束时间几乎完全一致。

这说明应用并非完全没有执行,而是一直在后台复制运行时。由于复制过程没有界面和进度提示,看起来就像点击图标毫无反应。

其中一次复制持续了约 15 分 40 秒,平均速度只有大约:

text 复制代码
0.28 MiB/s

即使复制了十几分钟,仍然没有完成。

六、为什么 D 盘上的复制会这么慢?

进一步检查发现:

  • C、D 两个分区位于同一块 NVMe SSD;
  • 两个分区健康状态正常;
  • 因此不是 D 盘硬盘性能太差;
  • D 盘上的 AppX 物理包目录带有 Encrypted 属性;
  • 复制目标位于 C 盘普通的 %LOCALAPPDATA% 目录。

换句话说,应用是在把 D 盘加密的 AppX 包资源复制到 C 盘的普通用户目录。

更关键的是,客户端代码使用了同步文件操作。

其逻辑可以简化为:

js 复制代码
// 同步读取并计算运行时文件哈希
hash = sha256(readFileSync(source))

// 同步递归遍历整个 cua_node
for (const file of files) {
  copyFileSync(source, destination)
}

代码还专门处理了 Windows 错误码 6000:

js 复制代码
try {
  copyFileSync(source, destination)
} catch (error) {
  if (error.errno === 6000) {
    writeFileSync(destination, readFileSync(source))
  }
}

Windows 错误码 6000 对应 ERROR_ENCRYPTION_FAILED,即加密文件复制失败。可以在 Microsoft System Error Codes 6000--8199 中查到。

当普通的 copyFileSync 无法直接处理加密资源时,应用会退化为:

  1. 把整个文件同步读入内存;
  2. 再同步写入目标目录;
  3. 对数千个文件重复这个过程。

而这一切发生在 Electron 主进程中。

七、为什么会出现单线程高占用、始终没有窗口?

Electron 的窗口创建、事件处理和一部分启动逻辑都依赖主线程。

但 ChatGPT 在窗口创建前执行了大量同步操作:

  • 同步读取约 119 MiB 的关键文件并计算 SHA-256;
  • 同步遍历 4680 个文件;
  • 同步复制约 319 MiB 的运行时;
  • 遇到加密复制错误后,继续同步读写回退。

只要这些操作没有结束,主线程就无法及时处理窗口创建和界面事件。

最终表现就是:

text 复制代码
进程存在
CPU 单线程高占用
没有渲染进程或窗口
应用日志不再继续输出

失败启动的应用日志通常只留下三行:

text 复制代码
in_app_updates_policy_wait_started
Launching app
Appshot hotkey inactive

这并不意味着更新检查或 Appshot 本身是根因。它们只是主线程进入同步运行时搬运之前,最后成功写入日志的步骤。

Windows 最终也记录了正式的应用挂起事件:

text 复制代码
EventName: MoAppHang
HangType: Quiesce
AppName: ChatGPT.exe

八、为什么移动到 C 盘后立即恢复?

Windows 在设置中执行移动后,同一个应用版本从 D 盘迁移到了 C 盘。

移动前:

text 复制代码
应用包:D:\WindowsApps\...
运行时目标:C:\Users\...\AppData\Local\OpenAI\Codex\...
应用包属性:Encrypted

移动后:

text 复制代码
应用包:C:\Program Files\WindowsApps\...
运行时目标:C:\Users\...\AppData\Local\OpenAI\Codex\...
应用包不再来自 D 盘加密 AppX 卷

移动后的首次成功启动时间线为:

text 复制代码
12:07:44  启动同一个 26.825.6671.0 版本
12:07:47  开始创建完整运行时目录
12:07:56  318.88 MiB、4680 个文件复制完成
12:08:06  主窗口完成加载并显示

原来十几分钟都无法完成的复制,在 C 盘大约 9 秒就完成了。

因此,移动到 C 盘有效的决定性原因不是修复了所谓的注册分裂,而是:

它让 ChatGPT 不再从 D 盘加密的 AppX 包目录同步搬运运行时,极大降低了启动阶段的复制成本。

九、这是 Windows 的问题,还是 ChatGPT 的问题?

两边的设计共同触发了问题,但更直接的缺陷在应用侧。

Windows 允许 Microsoft Store/MSIX 应用安装在非系统卷,这本身是受支持的能力。问题在于 ChatGPT:

  • 在窗口创建前搬运数百 MiB 运行时;
  • 使用同步递归复制;
  • 在主线程上同步计算大文件哈希;
  • 对加密复制失败逐文件执行同步回退;
  • 没有启动进度提示;
  • 没有合理超时;
  • 没有把耗时操作放到工作线程;
  • 进程被结束后留下大量未完成暂存目录。

更合理的实现方式应该包括:

  • 将运行时物化放入后台线程或独立进程;
  • 先创建启动窗口并显示进度;
  • 使用异步流式复制;
  • 对 EFS 加密包使用专门的解密目标复制策略;
  • 为失败复制提供日志、超时和重试上限;
  • 下次启动时清理或复用有效的暂存数据。

因此,这更像是 ChatGPT Windows 客户端在非系统 AppX 卷场景下的启动健壮性问题。

十、如何判断自己是不是同一个问题?

可以先检查 ChatGPT 包信息:

powershell 复制代码
$OutputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::new($false)

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

需要注意:InstallLocation 可能显示 C 盘逻辑入口,不能仅凭这一项判断物理文件在哪个盘。

然后检查运行时目录:

powershell 复制代码
$runtimeRoot = Join-Path $env:LOCALAPPDATA "OpenAI/Codex/runtimes/cua_node"

Get-ChildItem -LiteralPath $runtimeRoot -Force -Directory |
    Select-Object Name, CreationTime, LastWriteTime

如果存在大量这样的目录:

text 复制代码
.staging-xxxxxxxxxxxxxxxx-xxxxxx

而没有对应的完整 16 位哈希目录,就很可能卡在运行时搬运阶段。

应用日志通常位于:

text 复制代码
%LOCALAPPDATA%\Packages\OpenAI.Codex_2p2nqsd0c76g0\
LocalCache\Local\Codex\Logs

还可以检查最近的应用挂起事件:

powershell 复制代码
Get-WinEvent -FilterHashtable @{
    LogName   = "Application"
    Id        = 1002
    StartTime = (Get-Date).AddDays(-7)
} | Where-Object {
    ($_.Properties.Value -join "|") -match "ChatGPT|OpenAI\.Codex"
} | Select-Object TimeCreated, Id, RecordId

十一、总结

如果你足够有耐心的话,可以不修改这个 bug,理论上,你只要等足够长的时间,它就会打开。因为我之前就有一次,当时看着其他文档时,它突然蹦了出来,当时以为是什么时候不小心点到了,可能实际上是它从 D 盘复制到 C 盘成功了。

不过需要提醒:等待能否成功,取决于最新 staging 目录是否仍在持续增长。如果文件数、大小和修改时间长时间不再变化,或者不断产生新的 staging 目录,继续等待通常没有意义,建议直接按上文方法移动到 C 盘。

十二、相关公开问题

OpenAI 的公开问题列表中已经有高度相似的报告:

这些公开问题证明并非个别机器才会出现该现象,但本文分析的同步运行时搬运和 EFS 回退机制,主要来自本机日志、残留文件与客户端包内代码的交叉验证,尚不能代表 OpenAI 官方已经确认相同根因。

十三、为什么以前在 D 盘没事,更新后才出现?

1. 正常启动不一定每次都复制 319 MiB

cua_node 的正式缓存目录由运行时内容哈希标识。启动时如果已经存在与当前包匹配、带完整清单的缓存目录,客户端可以直接复用;只有缓存缺失、哈希变化或缓存不完整时,才需要创建新的 .staging-* 并重新搬运整套运行时。

因此,同一个应用在 D 盘连续正常使用数月并不矛盾。旧版本很可能一直命中已经完成的缓存,没有在每次启动时重新复制数千个受保护文件。

2. 这次更新改变了启动前提

本机事件和文件时间线如下:

时间 发生的事情
更新前 ChatGPT 一直安装在 D 盘,并能正常启动
8 月 28 日 23:08 左右 26.825.4187.0 开始部署到 D 盘
后续故障启动 新运行时哈希没有对应的完整缓存,客户端反复创建 .staging-*;共留下 21 个未完成目录
9 月 1 日 11:48 26.825.6671.0 仍注册到 D 盘
11:50、12:00 26.825.6671.0 在 D 盘启动,仍然只有进程、没有窗口
12:04 Windows 将同一个 26.825.6671.0 成功移动到目标卷 C:
12:07--12:08 同一版本重新启动,运行时约 9 秒准备完成,窗口随即出现

最符合这些证据的过程是:

text 复制代码
旧版本日常启动
→ 已有完整的旧运行时缓存
→ 哈希匹配,直接复用
→ 正常创建窗口

更新后首次启动
→ 当前包需要另一份运行时缓存
→ 没有匹配的完整目录
→ 从 D:\WindowsApps 创建新的 staging
→ 受保护文件跨卷复制异常缓慢或无法完成
→ 主线程被占用,窗口无法创建

同一版本移动到 C 盘后
→ 从 C 盘重新物化运行时
→ staging 正常完成并转为正式目录
→ 窗口恢复

3. 为什么不能简单认为这次更新新引入了 bug?

OpenAI 公开仓库中的 #34764 在更早的 26.715 版本就记录过高度一致的现象:非系统 AppX 卷、WindowsApps 文件受保护、复制返回错误 6000,以及移动到 C 盘后恢复。这说明底层薄弱点至少在更早版本已经存在。

本机现在能够确认的是:

  • 故障确实紧跟 26.825.4187.0 更新出现;
  • 该版本的启动确实反复创建了新的运行时暂存目录;
  • D 盘包资源确实带有 Encrypted 属性;
  • 后续版本在 D 盘仍失败,而同一版本移动到 C 盘后成功。

但旧包已经被 Store 替换,无法再对比旧版本的 cua_node 内容、哈希、复制实现和文件保护属性,也就无法把变化精确定位到某一个 OpenAI 代码提交或某一次 Windows Store 部署行为。

所以更严谨的结论是:

8 月 28 日的更新改变了运行时缓存条件,迫使客户端重新物化 cua_node,从而在这台机器上首次暴露了一个此前已经潜伏的非系统 AppX 卷 + 受保护文件 + 主进程同步复制缺陷;它是本次故障的触发点,不等于已经证明它是缺陷的最初来源。

这也解释了为什么不是每次更新都会复发:如果某次更新继续使用同一个运行时哈希,完整缓存仍可复用;只有运行时内容变化、缓存失效或需要重建时,才更容易再次触发。

因为我的电脑这个问题已经修复了,之前的旧包也已经覆盖了,没有办法对比了,如果有大佬知道是为什么,可以在评论区说一下。

额外了解------为什么复制会这么慢?

最核心的一点是:这并不是一次普通的 D 盘到 C 盘文件复制。对于受影响的文件,客户端会先尝试保留源文件加密属性的正常复制;这条路径失败后,再退化为同步解密、读取和写入。

一个文件大致会经历下面的处理链:

text 复制代码
读取源文件并计算哈希
        ↓
copyFileSync 尝试正常复制
        ↓
Windows 尝试把源文件的 EFS 加密信息应用到目标文件
        ↓
目标文件加密失败,返回错误 6000
        ↓
readFileSync 通过 EFS 解密并读取源文件
        ↓
writeFileSync 把内容写入 C 盘普通目录
        ↓
处理下一个文件

1. 正常复制路径会先失败一次

D 盘 WindowsApps 中的源文件带有 Encrypted 属性。根据 Microsoft 的说明,Windows 复制 EFS 加密文件时,会先尝试使用源文件的加密密钥加密目标文件;如果不成功,再尝试使用默认密钥。两种方式都失败后,复制操作才返回 ERROR_ENCRYPTION_FAILED,也就是错误码 6000。

参考:Microsoft:Handling Encrypted Files and Directories

因此,每个受影响的文件都可能先经历:

  • 打开源文件;
  • 查询加密属性和密钥;
  • 调用 EFS 服务;
  • 创建或准备目标文件;
  • 尝试应用加密;
  • 最后失败并抛出错误。

这次失败不一定已经复制了整个文件,但它会增加额外的文件系统、权限检查和加密服务开销。

2. 失败后还要重新读取并写入

从本地客户端包内代码观察到的简化逻辑如下:

js 复制代码
try {
  copyFileSync(source, destination)
} catch (error) {
  if (error.errno === 6000) {
    writeFileSync(destination, readFileSync(source))
  }
}

发生错误 6000 后,客户端不再要求 Windows 保留原文件的加密状态,而是:

  1. 再次打开 D 盘上的加密源文件;
  2. 通过 EFS 解密路径读取文件内容;
  3. 将完整内容放入内存;
  4. 在 C 盘目标目录中创建普通文件;
  5. 把内存中的内容同步写入目标文件。

如果复制前还要计算 SHA-256,那么同一份数据还需要先被完整读取一次。一次处理可能包含:

text 复制代码
第一次读取:计算哈希
第二次操作:尝试正常加密复制并失败
第三次读取:解密并读入内存
第四次操作:写入目标文件

因此,实际工作量明显高于资源管理器中的普通复制。

3. 大量小文件会放大固定开销

cua_node 运行时并不是一个连续的大文件,而是由大量 JavaScript、JSON、原生模块和依赖文件组成。

复制一个 1 GiB 的大文件,耗时通常主要取决于磁盘连续读写速度;复制数千个小文件时,大量时间则消耗在:

  • 打开和关闭文件;
  • 创建目录和文件;
  • 查询权限、属性和加密信息;
  • 分配与释放内存;
  • 更新 NTFS 元数据;
  • 对新生成的脚本、可执行文件和原生模块进行安全扫描。

最后一项是否发生、耗时多少取决于本机安全软件配置,并非本次日志已经确认的主因;但它可能进一步放大小文件写入的成本。

虽然 C、D 两个分区位于同一块 NVMe SSD,但它们仍是两个独立文件系统卷。跨卷操作需要真正读取源数据并写入目标卷,两个方向还会共享同一块 SSD 的控制器与闪存通道,不能因为位于同一块物理硬盘上就视为零成本操作。

不过,约 319 MiB 的正常复制本身不应该长时间卡住。真正异常的是加密处理、逐文件同步操作和失败后的重复劳动叠加。

4. 同步接口让复制串行化,也让窗口无法创建

copyFileSync、readFileSync 和 writeFileSync 都是同步接口:

Node.js:File system 文档

同步接口并不会单独降低某一次内核复制的速度,但它有两个重要影响:

  1. 当前文件没有处理完之前,程序不能开始处理下一个文件;
  2. 如果这些操作运行在 Electron 主进程中,窗口创建和界面事件也必须等待。

也就是说,应用不是在后台慢慢准备、同时先显示一个启动界面,而是把窗口创建也堵在了运行时准备流程后面。于是任务管理器里能看到进程和单线程高占用,桌面上却始终没有窗口。

5. 3.78 GiB 是失败残留的累计值

本机排查时发现:

text 复制代码
未完成的 .staging-* 目录:21 个
残留文件:23,832 个
占用空间:约 3.78 GiB

这不代表一次启动需要复制 3.78 GiB。它是多次未完成操作留下的累计结果。

每次启动都可能经历:

text 复制代码
创建新的 staging 目录
        ↓
复制一部分运行时文件
        ↓
复制失败、进程退出或被用户结束
        ↓
下次启动创建另一个 staging 目录
        ↓
再次执行前面的哈希和复制

因此,用户感受到的"复制非常慢",有时实际是"大量重复劳动,并且每次都没有到达完成状态",而不是同一次复制一直在稳定前进。

多个 staging 目录只能证明发生过多次未完成的准备过程,不能单凭它判断这些过程全部由应用自动重试产生;反复点击图标、手动结束进程或重启电脑,同样可能留下新的暂存目录。

6. 为什么移动到 C 盘后很快恢复?

移动到 C 盘会触发一次重新部署。根据本机移动后的检查,同一版本不再触发原先的 EFS 跨卷复制失败,运行时准备可以走正常路径:

text 复制代码
计算哈希
        ↓
正常复制
        ↓
staging 目录重命名为正式运行时目录
        ↓
创建应用窗口

本机实测,移动后同一版本的运行时准备约 9 秒完成。因此,改善的关键并不是"C 盘物理速度一定比 D 盘快",而是新的部署状态绕开了原先的加密复制失败和同步回退路径。

7. 是否只要等待足够久就能打开?

只有当所有文件最终都能成功处理,并且最新 staging 目录的文件数、大小和修改时间持续增长时,单次不受打断的启动才有可能在等待后完成。

如果出现以下情况,继续等待通常没有意义:

  • 最新 staging 目录长时间不再变化;
  • 不断产生新的 staging 目录;
  • 始终无法生成最终 manifest.json;
  • 同一个加密、权限或校验错误反复出现。

所以这次问题更准确的描述不是"D 盘太慢",而是:

D 盘 AppX 包的加密属性使正常复制路径失败,客户端随后采用同步、逐文件的解密读写方式兜底;大量小文件、哈希计算和多次未完成操作共同放大了启动时间,并阻塞了 Electron 窗口创建。

相关推荐
QZSJTR22 分钟前
2026年AI搜索引擎技术原理与GEO优化实战:从RAG到AI Agent
人工智能·搜索引擎·chatgpt
凭君语未可3 小时前
CC Switch 切换 Codex 中转站后历史会话打不开?一次 model_provider 绑定问题的排查与解决
chatgpt
还是大剑师兰特3 小时前
MySQL8.0 Windows完整安装教程
windows·mysql·大剑师
梦想出海-Phoebe4 小时前
ChatGPT 被欧盟纳入大型搜索服务监管:AI 正在变成新的信息入口
人工智能·chatgpt
redfred5 小时前
HandBrake 使用教程:开源视频压缩工具 视频太大压缩 MKV转MP4 批量转码 硬件加速 Windows/macOS/Linux
windows·开源·音视频
kingbal6 小时前
MAC:chatgpt登陆报错签名异常
macos·chatgpt
kakakahahahaha6 小时前
【Windows】C盘拒绝访问0x80070005的7步排查
windows·电脑·内容运营·软件需求
T型码农要学习8 小时前
Open WebUI:给本地AI装上网页界面,完美平替ChatGPT
人工智能·chatgpt
万年咸鱼8 小时前
Java ArrayList 详解:原理、用法与实战
java·开发语言·windows