
这台 ThinkPad P1 Gen5(i9-12900H,RTX A5500)是我跑解算用的。电源方案是自定义的满性能方案,名字就叫 Ultimate-ANSYS,任何省电模式都不许开,这是我给这台机器定的铁律。从 5 月底开始,它开机越来越慢:有时登录后黑屏一两分钟,有时停在欢迎界面不动,进了桌面点开微信还要再等几十秒。到 8 月底前后查出四层原因:关掉快速启动以后暴露出来的卡死自启服务;系统代理指向一个还没起来的本地端口,登录期的凭据同步全在超时;代理客户端一启动,又把放行白名单写回原样;微信每次登录要加载 4.7 GB 的本地消息库,换网后的 DNS 又在放大它。前两层修了,第四层改了用法,第三层还挂着:10 月 15 日写这篇时复查,白名单又没了。
排查是我和 Claude Code 一起做的。我负责描述现象、重启、盯屏幕,它翻事件日志、改配置、做对照测试。中间它下过好几次错结论,有的是我坚持现象不对才翻过来的,这些也照实写。

起点:快速启动是为 USB-C 关的
5 月 30 日,为了治 USB-C 口不充电(那是另一篇),我把快速启动关了,注册表里 HiberbootEnabled 从 1 改成 0。快速启动开着的时候,关机其实是半休眠,开机时直接把已经启动好的服务状态从休眠文件里恢复回来;关掉以后每次都是完整冷启动,服务管理器要把所有自动启动的服务从头拉一遍。以前那些根本起不来的服务被遮住了,现在每次都要等它们超时。
开回快速启动最省事,但 USB-C 那边需要它关着,6 月 22 日我明确说了不开。电源方案也不能动。能做的只剩一件事:把开机路径上每个在等的东西找出来,一个一个拿掉。
6 月:冷启动暴露出来的一串超时
6 月 14 日我是这么描述的:按下电源到听见系统声音很快,可有声音的时候屏幕是黑的,黑一分多钟才到登录界面。那次开机的事件日志排出来(以内核启动为 T0):T+33 s 出登录界面,T+53 s 密码验证通过,然后从 T+54 s 到 T+179 s 整整 125 秒黑屏,直到一个空 CLSID 的 DCOM 服务器注册超时放弃,桌面才开始加载。
在等的东西有四个。Intel(R) Platform License Manager Service 和 Google 的 gupdate 都是自动启动、都卡死,各自把服务管理器的 120 秒等满(事件 7009);一个空 CLSID 的 DCOM 注册失败(事件 10010),大约 80 秒,它一超时桌面就出来;还有一个启动就失败的 ElevationService。找它们用的是一句很朴素的查询:
Get-CimInstance Win32_Service | ? { $_.StartMode -eq 'Auto' -and $_.State -ne 'Running' }处理方式是改成手动启动,不卸载:
Set-Service -Name 'Intel(R) Platform License Manager Service' -StartupType Manual
Set-Service -Name 'ElevationService' -StartupType Manual一共改了 7 个,除了上面三个,还有 Google 和夸克各两个更新服务。当天下一次冷启动,7009 全部消失。顺手还禁了 12 个登录启动项、13 个更新器和遥测的计划任务。我又说许可证、银行、工程软件这类服务用得很少,不需要常驻,于是又有 18 个重型服务改成手动,里面有 ANSYS 和 FlexNet 的许可证服务、MySQL、两家银行的网银盾。这一步是有代价的:7 月 2 日我要开 ANSYS,许可证服务报错,就是因为它被改成了手动。许可证和数据库这类服务不会被应用自动拉起来,用之前得先 Start-Service。
6 月 15 日我又强调了一次:问题是启动后黑屏的时间特别久。这次怀疑到了显示链路上,把一款远程桌面软件装的虚拟显示器驱动、连同两个幽灵扩展坞显示设备一起清掉以后,登录界面从 T+30 s 提前到 T+21 s,桌面从 T+111 s 提前到 T+90 s。数字好看了,可黑屏的真因不在这里。
6 月 23 日拔着电源开机,黑了几分钟才出登录框。Claude Code 看到登录相关的事件在 T+22 s 就出现了,往 BIOS、开机自检那边去找。我不认,当时的原话是(6 月 23 日):
windows绝对没有22秒就到登录框了,假如已经到了登录框,说明有别的程序阻止了显示登录框。
回去翻 Winlogon 的操作日志,T+27 s 到 T+262 s 之间有一个 235 秒的间隙,收尾的是事件 6000:"通知订户 SessionEnv 无法处理通知事件"。SessionEnv 是远程桌面配置服务,它的登录通知要等网络,而那次电池冷启动 WiFi 到 T+288 s 才连上,它就一直等到自己超时。T+22 s 出现的只是登录界面的内部事件,不等于登录框已经画出来了。远程桌面本来就关着,SessionEnv 直接禁用。
6 月 25 日把这一串收拢成一个级联:快速启动关着,每次都完整冷启动;电池上 CPU 只跑基频;几十个第三方服务和应用一起初始化,把 CPU 挤满;网络也卡在拥堵里;依赖网络的登录组件一个接一个干等超时。禁掉一款备份软件的三个常驻项以后,反复出现的 DCOM 空 CLSID 超时变成 0 次,Schannel 的 TLS 报错从 82 条降到 42 条,WiFi 连上从 178~288 s 提前到 116 s。剩下大约 73 秒的空档(登录 T+22 s,桌面 T+101 s)里已经没有卡死的服务,剩下的是 TPM 度量启动、安全特性和服务冷启动叠在一起的正常重活。Razer 的三个服务改成了延迟启动。还有一条很实用:先插电,再按电源键。那次开机的前 15 秒其实是在电池上跑的。
6 月 26 日我坚持以前电池下也能看到睿频,要查的是软件设置。处理器电源策略全部改成性能优先(睿频模式、EPP=0),BIOS 里电池模式的散热策略本来就是 MaximizePerformance。然后用性能计数器 % Processor Performance 实测:电池下单核轻载能到 169%,大约 4.2 GHz,睿频没坏;全核重载只有 110% 左右,整机放电只有 50 W 上下,i9 全核睿频要 100 W 以上,电池喂不出来。冷启动恰好就是全核重载。顺带一个坑:Win32_Processor.CurrentClockSpeed 永远报 2500,不能拿来看频率。
WiFi 晚到是同一时期的支线,口径改过好几次。一开始以为是电池供电触发了固件限速,把 WLAN 服务饿死了;接交流电复测照样限速 71 秒,又改口成冷启动负载撞上了功率墙;6 月 26 日的结论是 WLAN 服务自己内部初始化慢了 72 秒、关联又慢了 82 秒,和供电、配置文件数、过滤驱动都无关。配置文件从 400 个清到 32 个,还发现网络位置感知服务 NlaSvc 不知被谁改成了手动并停止(右下角不显示已联网就是它),改回自动。真因没抓到,留了一个开机探针计划任务。
7 月 17 日:欢迎界面停了 67.8 秒
7 月 17 日凌晨重启后,我只说了一句:这次在欢迎界面停了非常久。
先排除。这次开机按 6 月的指标反而是最好的一次:解锁 T+42.4 s,WiFi T+37.4 s 就连上,固件限速 0 次,没有服务超时,没有 DCOM 空 CLSID,说明 6 月那些修改都还在生效。也不是 Claude Code:它 15 秒就就绪了,我感觉它慢的那两分四十秒其实是 /compact 在跑。全局配置里一个 playwright MCP 的写法是坏的(整条 npx @playwright/mcp@latest 塞进了 command,args 是空的),一度怀疑是它冷启动 npx 拖住了欢迎界面,实测它 0.0 秒就失败,背不了这个锅,我让它直接删了。
真正的时间线:安全日志里 LogonType=7 的那条 4624 是解锁,T+42.4 s(T+23 s 那条"身份验证结果 0"不是用户登录);Winlogon 的 811/812 订户通知在 T+42.4 s 到 T+110.1 s 之间空了 67.8 秒;本地代理客户端的进程在 T+119.0 s 才启动,比空档结束还晚 8 秒。
原因在注册表里。HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings 下的 ProxyEnable=1、ProxyServer=127.0.0.1:<端口> 一直留着,而本地代理客户端没有任何自启项(Run 键、启动文件夹、计划任务都没有),是我进了桌面手动开的。于是开机头两分钟,系统被配置成把所有 WinINET 流量交给一个没人监听的端口。网络本身是通的,网络状态探测也报正常,只是流量被指错了地方。空档里全是登录期的网络操作在重试和超时:凭据保管库(CloudStore)下载失败在 T+82 s,Crypto-NCrypt 的"加密操作失败"在 T+83~84 s 成批刷了几十条,还有 Schannel 36871、Windows Hello 预配放弃、MDM 配置管理器失败。全部超时放弃之后,桌面才出来。这也解释了它为什么时有时无:取决于上次关机时代理设置有没有留在注册表里,以及我多快把客户端打开。

修法是给 ProxyOverride 加白名单,让登录期要访问的微软域名绕过代理直连,ProxyEnable 和 ProxyServer 都不动,代理照常用:
<local>;*.live.com;*.microsoft.com;*.windows.com;*.msftconnecttest.com;*.msftncsi.com怎么证明白名单真的生效
这次排障里最值得记的是这一段。有两个顺手的验证办法,都会骗人。
第一个是 .NET 的 [Net.WebRequest]::GetSystemWebProxy().GetProxy()。拿它问 login.live.com 走不走代理,它回答走代理,看上去白名单没生效。原因是它判断绕过用的是正则,还拿 scheme://host:port 整串去匹配,*.live.com 这种 WinINET 的写法它判不中,结果是假阴性。WinINET 的事要用 WinINET 自己验:P/Invoke 调 InternetOpen(访问类型 0,用系统预配置)再 InternetOpenUrl。
第二个是裸 TCP 连接。握手成功证明不了直连可用,有的网络放过 TCP 握手,等到 TLS ClientHello 再按 SNI 断开。要用 SslStream.AuthenticateAsClient 发一个真的 ClientHello。那天实测 7 个微软域名 TLS 直连全部正常,0.2 秒级,这台机器上不存在这个问题,但不测就不知道。
最后起决定作用的是死端口复现:把 ProxyServer 临时改成 127.0.0.1:9(没人监听),复现开机那两分钟的状态,对比名单内的域名和名单外的对照组,用 try/finally 保证改完一定还原。7 月 17 日的结果是 login.live.com 200(0.9 s)、account.live.com 200、settings-win.data.microsoft.com 404、msftconnecttest 200(0.4 s),全部绕过成功;对照组 baidu 和 google 全部报 12029(连不上代理),说明测试本身是有效的;代理还原后 google、github 都是 200。
有一条没想通:*.microsoftonline.com 这条规则在死端口下稳定 2.1 秒失败,和走代理的对照组耗时一样,可它直连 TLS 是好的,同一个名单里的 *.live.com、*.microsoft.com 也都生效。原因没查出来,从名单里删了(那是 Azure AD 企业账号用的,这台机器登的是个人微软账号)。login.windows.net 也删了,它某次裸 TCP 6 秒超时,多半是抖动,但没必要冒险。
写这篇时(10 月 15 日)我又跑了一遍,这次没去改注册表:WinINET 的 InternetOpen 用访问类型 3(INTERNET_OPEN_TYPE_PROXY),代理和绕过名单只设在这一个句柄上,效果一样,不影响机器上的其他程序。函数是这样的:
function Test-DeadPort([string]$Url, [string]$Proxy, [string]$Bypass) {
# accessType 3 = INTERNET_OPEN_TYPE_PROXY:代理只作用于这个句柄,不改注册表
$h = [WinInet]::InternetOpen('deadport-test', 3, $Proxy, $Bypass, 0)
$t = 8000; [void][WinInet]::InternetSetOption($h, 2, [ref]$t, 4)
$sw = [Diagnostics.Stopwatch]::StartNew()
$r = [WinInet]::InternetOpenUrl($h, $Url, $null, 0, 0x84000200u, [IntPtr]::Zero) # RELOAD | NO_CACHE_WRITE | NO_UI
$err = [Runtime.InteropServices.Marshal]::GetLastWin32Error(); $sw.Stop()
if ($r -ne [IntPtr]::Zero) {
$code = 0; $len = 4
[void][WinInet]::HttpQueryInfo($r, 0x20000013, [ref]$code, [ref]$len, [IntPtr]::Zero)
$res = "HTTP $code"; [void][WinInet]::InternetCloseHandle($r)
} else { $res = "失败 $err" }
[void][WinInet]::InternetCloseHandle($h)
[pscustomobject]@{ URL = $Url; Result = $res; Seconds = [math]::Round($sw.Elapsed.TotalSeconds, 1) }
}[WinInet] 是用 Add-Type 声明的几个 wininet.dll 函数,完整脚本放在素材目录里。标志位那里要写成 0x84000200u,不带 u 的话 PowerShell 会把它解析成负的 Int32,传不进 uint 参数。

截图前那次试跑,account.live.com 失败了一次(12029,4.9 秒)。追了一下:它现在会 301 跳到 account.microsoft.com,跳转链上的域名都在名单内,单独逐跳请求每一跳都通,再连跑 4 遍全是 200。单次失败不能当结论,至少多跑几遍,这和当初删 login.windows.net 是同一个道理。
下次开机的验收标准也是事先定好的:重算 Winlogon 811/812 相邻事件的间隙,看那 67.8 秒还在不在。
8 月 17 日的插曲:开机弹出来的 PowerShell 窗口
8 月 17 日开机后,一个 PowerShell 窗口挂了两分多钟。查下来是 7 月底给一个电机仿真项目建的登录计划任务,本来用来在重启后接着跑算例,那个算例 7 月 30 日就封存了,任务每次登录只写一行日志就退出。脚本明明带了 -WindowStyle Hidden,窗口还是出来了:我的默认终端是 Windows Terminal,pwsh 一启动弹的是 Windows Terminal 的窗口,-WindowStyle Hidden 只能藏 pwsh 自己的伪控制台,藏不住它。平时 pwsh 一秒不到就退,一闪而过;开机负载下冷启动慢,窗口就挂了两分多钟。我说删掉,任务删了,脚本留着。
8 月 31 日:点开微信卡几十秒
8 月 31 日晚上我问的是:为什么点微信要过好几十秒才登得上,中间卡住几十秒。
第一反应是 7 月那层又回来了。查注册表,ProxyOverride 果然只剩 <local>,7 月 17 日记下的"待观察"应验了:代理客户端启动时会把这个值覆写回去,白名单已经丢了。但这和微信无关。实测启动一次微信,2 秒出窗口,直接用 TCP 连腾讯的服务器,完全不碰本地代理端口,这个版本的微信不走系统代理。
那次卡顿另有原因,是事件日志加上微信自己的文件拼出来的。那天傍晚我在一个网络下让电脑睡眠,带着它换了地方,唤醒后连上了另一个网络;一分多钟后 Wi-Fi 闪断一次,系统判定"互联网能力清零",15 秒后恢复;又过了一分半我点了微信,26 秒后微信重写了自己的服务器 IP 缓存(ip.ini 和 host-redirect.xml),说明换网后旧缓存里的服务器地址在逐个超时,它重新做了一遍服务器发现。它网络统计文件名里像是耗时的字段,从 30500 毫秒一路降到 365、254 毫秒,和"卡几十秒然后自己好了"对得上。放大器是那个网络的路由器:双层 NAT,DHCP 下发的首选 DNS 是跨子网的上级路由,健康时解析也要 277 ms,比直接问网关的 35 ms 慢 8 倍,刚唤醒和闪断的时候更是整个不可达,而微信登录要串行解析一串域名,每个都先等首选 DNS 超时。
我又补了一句:"还有就是我在任何网络下,都有微信点开然后等好久这个事情"。这说明还有一个每次都在的慢因子,换网只是放大器。之前测的只是出窗口那 2 秒,没测我真正卡的那段。于是起了一个 0.7 秒采一次的采样器,记微信进程的磁盘读取、CPU、内存和 TCP 连接状态,我照常登录一遍。点下"进入微信"之后,有 16~22 秒是纯本地的重活:CPU 累计多用了 30 秒,相当于 1.2 个核一直满转,磁盘读了大约 400 MB,内存从 190 MB 涨到 750 MB。这期间网络没有任何阻塞,抓到的几个半开连接是登录后批量拉聊天图片,对那几个 CDN 地址测 80、443 端口都是通的。
我的微信数据一共 71.8 GB:聊天里的图片视频 64.6 GB,登录时不加载;消息数据库 4.7 GB,登录卡的就是加载它;缓存 2.2 GB。那晚是最好的条件,机器热着、缓存是暖的,还要 20 秒。平时我是刚开机、刚唤醒就点微信,缓存全冷,CPU 还在忙开机那堆活,电池上还只跑基频,同样的 400 MB 就被拉成了几十秒。采样还录到我点 X 时微信进程整个退出了,设置里选的是退出微信,所以每次打开都要重付一遍。处方在微信自己的设置里:关闭主面板时改成最小化到托盘,一天只付一次;要缩短那一次,清的是聊天记录(缩消息库),清图片视频只省磁盘,基本不提速。
采样器自己也踩了个坑。收尾时数据尾部看着像是微信进程中途重启过、还冒出一堆半开连接,其实是磁盘读数过了 1000 MB 以后被格式化成了 1,906,千分位的逗号把 CSV 的列挤歪了。按真实值还原,尾声很干净:登录后它又从库里读了 1.35 GB,到采样结束累计读了大约 1.9 GB。
DNS 那边,Claude Code 先给 Wi-Fi 网卡设了固定的公共 DNS,解析降到 35 ms 左右。我没同意,原话是(8 月 31 日):
不不,我要求酒店或者星巴克自动弹登录页。
固定 DNS 会让酒店和咖啡店的认证页弹不出来。最后的做法是按 SSID 切换:计划任务 SsidDnsSwitch 以 SYSTEM 身份运行,不弹窗口,电池上也跑,触发条件是 WLAN 连上(事件 8001)、断开(8003)和开机。脚本看当前 SSID 在不在白名单里,在就切到公共 DNS,不在就恢复成 DHCP 下发的原样,认证页的行为和以前完全一样。下面是脱敏后的节选:
$FastSsids = @('<白名单网络>') # 想加速的网络加在这里
$FastDns = @('<公共DNS-1>', '<公共DNS-2>')
$Alias = 'Wi-Fi'
$ssid = $null
$line = (netsh wlan show interfaces) | Where-Object { $_ -match '^\s*SSID\s*:\s*(.+)$' } | Select-Object -First 1
if ($line -match '^\s*SSID\s*:\s*(.+)$') { $ssid = $Matches[1].Trim() }
if ($ssid -and ($FastSsids -contains $ssid)) {
Set-DnsClientServerAddress -InterfaceAlias $Alias -ServerAddresses $FastDns
} else {
Set-DnsClientServerAddress -InterfaceAlias $Alias -ResetServerAddresses
}当晚手动触发验证了两条路:在白名单网络上切到了公共 DNS;恢复 DHCP 以后,路由器下发的 DNS 也回来了。真实换网能不能触发,当时只能等。现在可以回答了:从 8 月 31 日到 10 月 14 日,日志一共 266 条,分布在 43 天里,碰到过 30 个不同的 Wi-Fi;除了第一条是当晚手动触发的,其余都是计划任务自己触发的。

现在的状态
10 月 15 日复查:

ProxyOverride 还是只有 <local>。9 月 21 日查别的网络问题时顺手看过一眼,也是 <local>,白名单从 8 月底丢了以后就没回来过。快速启动还关着,6 月改的服务也都还是手动或禁用。10 月 14 日那次开机,Winlogon 序列里最大的间隙是 5 秒,第一条通知在 T+45 s,资源管理器 T+61 s 起来,WiFi T+55 s 连上,服务超时 0 次,固件限速 0 次。这次没卡,不代表那层修好了:现在的代理监听进程是那天上午才起的,开机那会儿注册表里是什么状态,已经查不到了。
还挂着的事有三件。开机时用计划任务把白名单补回 ProxyOverride,就是图 2 里的修法 ②,还没做。Tailscale 的健康检查一直报"设置 DNS 配置失败:文件被占用",像是在和代理客户端抢 DNS 配置,没动。6 月装的 WiFi 开机探针还在每次开机时跑,记录我没再回头看。