关于 windows-remote-desktop-connection-doctor
用于在 macOS 上排查 Windows App 远程桌面连接问题,涵盖 AVD 系列云桌面和直连 PC。它结合网络检查、客户端日志分析及独立 RDP 探测,帮助区分可能原因并指导修复。
主要功能
- 01诊断 AVD 和直连 PC
- 02检查网络、VPN 与代理
- 03分析 Windows App 日志
- 04独立探测 RDP 服务端
- 05基于证据判断原因并指导修复
适用场景
- 01调查 AVD 连接退回 TCP 或 WebSocket 的情况
- 02检查 VPN 或 UDP 限制对 Shortpath 的影响
- 03诊断直连 PC 卡在连接配置阶段的问题
- 04区分客户端身份验证故障与服务端可达性问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ daymade/ claude-code-skills --skill windows-remote-desktop-connection-doctor安装后在 Claude Code 中输入/windows-remote-desktop-connection-doctor确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/avd_transport_protocols.mddirect_pc_and_auth_diagnostics.mdwindows_app_log_analysis.mdscripts/probe_rdp_server.py详细介绍
Windows 远程桌面连接诊断工具
在 macOS 上诊断并修复 Windows App(Microsoft Remote Desktop / AVD / WVD / W365 / 直接连接 PC)的连接问题,重点关注传输协议优化和根因证伪。
方法论基础: 通用的、以证据为依据的诊断规范见 debugging-network-issues 技能。此技能是 Windows App / AVD 传输的领域层——它更侧重于连接质量优化,而非根因证伪,因此与通用方法的重合较少。
背景
Azure Virtual Desktop 的传输优先级:UDP Shortpath > TCP > WebSocket。UDP Shortpath 可提供最佳体验(延迟最低,支持 UDP Multicast)。如果 UDP Shortpath 失败,客户端会回退到通过网关使用 TCP 443 的 WebSocket,从而显著增加延迟。
直接连接 PC 使用基于 TCP 3389 的标准 RDP(通常由 TLS 封装)。这类连接没有“连接信息”面板、没有网关可达性测试,也无需进行传输优化。对于直接连接 PC,主要故障模式包括:
- 远程 PC 已关机或无法访问(网络/防火墙问题)。
- Windows App 客户端中的 Microsoft 工作或学校帐户已过期或信息陈旧,导致身份验证协调流程出错,连接卡在“正在配置远程 PC…”。
- 远程 PC 已重启(通常由 Windows Update 触发),而客户端无法正常恢复连接。
此技能涵盖这两种场景。
诊断工作流
步骤 1:确定连接类型和症状
收集证据前,先确定要诊断的场景:
| 场景 | 主要特征 | 主要证据来源 |
|---|---|---|
| AVD/WVD/W365 | 用户通过工作区/网关连接到云桌面 | “连接信息”面板、网关运行状况检查、UDP Shortpath 日志 |
| 直接连接 PC | 用户通过主机名或 IP 连接到指定 PC(例如,家用工作站) | RDP 协议探测、Windows App 日志中的身份验证链、Windows 端重启事件 |
对于 AVD/WVD/W365,请让用户提供 Windows App 中的“连接信息”(点击工具栏中的信号图标)。需要提取的关键字段:
| 字段 | 含义 |
|---|---|
| 传输协议 | 当前传输方式:UDP、UDP Multicast、WebSocket 或 TCP |
| 往返时间(RTT) | 端到端延迟,单位为 ms |
| 可用带宽 | 当前带宽,单位为 Mbps |
| 网关 | AVD 网关主机名和端口 |
| 服务区域 | Azure 区域代码(例如,SEAS = 东南亚) |
如果传输协议为 UDP 或 UDP Multicast,则连接已达到最佳状态——无需进一步诊断。
如果传输协议为 WebSocket 或 TCP,请继续执行步骤 2。
对于直接连接 PC,“连接信息”面板不存在。请改为先运行步骤 2E 中的 RDP 协议探测,确认服务器可访问,然后分析 Windows App 日志,查找身份验证异常或重新连接失败。如果进度对话框卡在“正在配置远程 PC…”,应优先怀疑客户端身份问题(见类别 E)。
步骤 2:收集网络证据
并行收集证据——不要妄下结论。同时运行以下检查:
2A:网络接口和路由
ifconfig | grep -E "^[a-z]|inet |utun"
netstat -rn | head -40
scutil --proxy
请查找:
- utun 接口:识别 VPN/代理 TUN 隧道(ShadowRocket、Clash、Tailscale)
- 默认路由优先级:确定哪个接口处理默认流量
- 分流路由:
0/1 + 128.0/1 → utun模式表示 VPN 正在捕获所有流量 - 系统代理:是否在 localhost 端口启用了 HTTP/HTTPS 代理
2B:RDP 客户端进程和连接
# Find the Windows App process (NOT "msrdc" — the new client uses "Windows" as process name)
ps aux | grep -i -E 'msrdc|Windows' | grep -v grep
# Check its network connections
lsof -i -n -P 2>/dev/null | grep -i "Windows" | head -20
# Check for UDP connections
lsof -i UDP -n -P 2>/dev/null | head -30
需要查找的关键信息:
- 源 IP
198.18.0.x:流量正通过 ShadowRocket/代理 TUN 隧道进行路由 - 没有来自 Windows 进程的 UDP 连接:Shortpath 尚未建立
- 只有 TCP 443:已回退到网关 WebSocket 传输
2C:VPN/代理状态
# Environment proxy variables
env | grep -i proxy
# System proxy via scutil
scutil --proxy
# ShadowRocket config API (if accessible on local network)
NO_PROXY="<local-ip>" curl -s --connect-timeout 5 "http://<local-ip>:8080/api/read"
2D:Tailscale 状态(如果正在运行)
tailscale status
tailscale netcheck
netcheck 输出会显示 NAT 类型(MappingVariesByDestIP)、UDP 支持情况和公网 IP;即使问题与 Tailscale 无关,这些信息也很有价值。
2E:独立检查 RDP 服务端运行状况(直连 PC)
这一步对 直连 PC 至关重要,也可用于 AVD/WVD/W365 的证伪测试:它能证明服务端 RDP 协议栈运行正常,无需依赖 Windows App 客户端或任何凭据。
使用随附的探测脚本:
python3 scripts/probe_rdp_server.py <host> [port]
示例:
python3 scripts/probe_rdp_server.py my-pc.local 3389
探测成功时会报告 RDP server <host>:<port> is reachable and healthy (RDP + TLS).,这意味着问题出在 客户端(身份验证、应用状态、代理或身份)。探测失败则意味着问题出在 服务端或网络(PC 已关机、防火墙、端口不可达、TLS 拦截)。
有关探测结果的详细解读,请参阅 references/direct_pc_and_auth_diagnostics.md。
第 3 步:分析 Windows App 日志
这是最关键的一步。Windows App 日志包含网络层测试无法揭示的传输协商详情。
macOS 上的日志位置:
~/Library/Containers/com.microsoft.rdc.macos/Data/Library/Logs/Windows App/
文件名格式为:com.microsoft.rdc.macos_v<version>_<date>_<time>.log
**重要提示:**Windows App 日志时间戳采用 UTC。用户的时钟和 Windows 事件日志通常使用本地时间。构建时间线之前,请将所有时间戳转换为同一时区。
**按会话跟踪:**每次连接尝试都会获得一个以大括号括起的唯一活动 GUID。按 GUID 汇总事件,以了解单次尝试的生命周期。有关 GUID 汇总方法,请参阅 references/windows_app_log_analysis.md;有关直连 PC 故障特征,请参阅 references/direct_pc_and_auth_diagnostics.md。
有关详细的日志解析指南,请参阅 references/windows_app_log_analysis.md。
快速搜索日志
LOG_DIR=~/Library/Containers/com.microsoft.rdc.macos/Data/Library/Logs/Windows\ App
# Find the most recent log
LATEST_LOG=$(ls -t "$LOG_DIR"/*.log 2>/dev/null | head -1)
# Search for transport-critical entries (filter out noise)
grep -i -E "STUN|TURN|VPN|Routed|Shortpath|FetchClient|clientoption|GATEWAY.*ERR|Certificate.*valid|InternetConnectivity|Passed URL" "$LATEST_LOG" | grep -v "BasicStateManagement\|DynVC\|dynvcstat\|asynctransport"
关键日志模式
| 日志模式 | 含义 |
|---|---|
Passed: InternetConnectivity | 运行状况检查已成功完成 |
TCP/IP Traffic Routed Through VPN: No/Yes | 客户端检测到 TCP 流量通过 VPN 路由 |
STUN/TURN Traffic Routed Through VPN: Yes | 客户端检测到 STUN/TURN 流量通过 VPN 路由 |
Passed URL: https://...wvd.microsoft.com/ Response Time: Nms | 已确认网关可达 |
FetchClientOptions exception: Request timed out | **关键:**客户端无法从网关获取传输选项 |
Certificate validation failed | 检测到 TLS 拦截或 DNS 污染 |
OnRDWebRTCRedirectorRpc rtcSession not handled | 客户端未处理 WebRTC 会话设置 |
OneAuthError_InteractionRequired | 无法静默刷新缓存的 Microsoft 帐户令牌 |
No valid refresh tokens available in the cache | 身份验证请求没有可用的缓存凭据 |
credential completion has been canceled | 交互式登录提示已取消 |
GATEWAY(ERR): ... UserCancelled(8) | 登录已取消,导致身份验证协调失败 |
RDP_WAN: Client connMonitor goto CMSTATE_DROPPED | 连接监视器检测到会话已断开 |
Channel::StartWrite failed / GetBuffer failed | 传输已中断;客户端正在向已关闭的套接字写入数据 |
ParseUserData: No data of type 0xc09 | 非致命——服务端已响应 MCS Connect;这证明 TCP 通路正常 |
IHAddMouseEventToPDU / IHAddMouseWheelEventToPDU | 会话正常运行并正在接收输入 |
比较正常与异常日志
如果条件允许,请将连接正常时(UDP)的日志与当前日志进行比较:
# Compare startup health check blocks
for f in "$LOG_DIR"/*.log; do
echo "=== $(basename "$f") ==="
grep -E "InternetConnectivity|Routed Through VPN|Passed URL|FetchClient" "$f" | head -10
echo ""
done
正常日志会包含完整的运行状况检查区块(InternetConnectivity、VPN 路由检测、网关 URL 测试)。异常日志可能完全缺少这些条目,或者显示证书错误或超时错误。
第 4 步:确定根本原因
根据收集到的证据,确定根本原因类别:
类别 A:VPN/代理干扰
证据:Windows App 源 IP 为 198.18.0.x,STUN/TURN 经 VPN 路由,没有 UDP 连接。
修复方法:在代理工具中为 AVD 流量添加 DIRECT 规则:
DOMAIN-SUFFIX,wvd.microsoft.com,DIRECT
DOMAIN-SUFFIX,microsoft.com,DIRECT
IP-CIDR,13.104.0.0/14,DIRECT
验证方法:暂时禁用 VPN/代理,重新连接 VDI,检查传输方式是否切换为 UDP。
类别 B:ISP/网络限制 UDP
证据:即使关闭所有 VPN,仍使用 WebSocket。没有 UDP 连接。FetchClientOptions 超时。
验证方法:
# Test STUN connectivity to a known server
python3 -c "
import socket, struct, os
header = struct.pack('!HHI', 0x0001, 0, 0x2112A442) + os.urandom(12)
for srv in [('stun.l.google.com', 19302), ('stun1.l.google.com', 19302)]:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(3)
s.sendto(header, srv)
data, addr = s.recvfrom(1024)
print(f'STUN from {srv[0]}: OK')
s.close(); break
except: print(f'STUN from {srv[0]}: FAILED'); s.close()
"
修复选项:
- 尝试使用手机热点(将家庭网络与 ISP 隔离)
- 检查路由器 NAT 类型(优先使用 Full Cone NAT)
- 在路由器上启用 UPnP
- 如果可用,尝试使用 IPv6
- 联系 ISP,询问 UDP 限制
类别 C:客户端运行状况检查失败
证据:日志显示启动时出现证书验证错误,日志中缺少运行状况检查部分(InternetConnectivity、STUN/TURN 检测),FetchClientOptions 超时。
这意味着客户端无法完成诊断/功能发现,导致 Shortpath 协商无法进行。
可能原因:
- ISP HTTPS 拦截/MITM(尤其是在中国)
- DNS 污染,导致 Microsoft 诊断端点返回错误 IP
- 防火墙阻止 Microsoft 遥测端点
修复选项:
- 将 DNS 更改为 8.8.8.8 或 1.1.1.1(绕过 ISP DNS)
- 通过干净的代理路由 Microsoft 流量
- 检查 ISP 是否注入证书
类别 D:服务器端未启用 Shortpath
证据:日志中完全没有 STUN/TURN 或 Shortpath 相关条目(连检测记录也没有),但运行状况检查通过且没有错误。
这意味着 AVD 主机池未启用 RDP Shortpath。需要管理员在 Azure 门户中进行操作。
类别 E:客户端身份/过期 Microsoft 帐户污染(直连 PC 和 AVD)
证据:RDP 协议探测成功(服务器运行正常),但 Windows App 日志显示 OneAuth/MSAL 链中出现以下记录:
OneAuthError_InteractionRequiredNo valid refresh tokens available in the cacheAcquireTokenInteractivelycredential completion has been canceledUser canceled sign inGATEWAY(ERR): CWVDTransport::OnOrchestrationHttpError error: UserCancelled(8)Fail OnDisconnected call
进度对话框可能一直停留在“正在配置远程 PC……”,因为应用正在等待一个被隐藏或取消的交互式登录提示。即使过期帐户与该 PC 无关,这也可能影响直连 PC,因为 Windows App 客户端在所有连接类型中共用同一身份验证编排流程。
修复方法:打开 Windows App → Settings → Accounts,退出或移除过期的 Microsoft 工作或学校帐户,然后完全退出应用(Cmd+Q)并重新启动。再次尝试连接。
完整的特征集和故障排除步骤请参阅 references/direct_pc_and_auth_diagnostics.md。
类别 F:服务器端重启/Windows Update
证据:之前正常工作的会话突然断开,随后无法重新连接。Windows App 日志显示 CMSTATE_DROPPED,可能还会出现 Channel::StartWrite failed。Windows PC 的 LastBootUpTime 与断开时间接近,且事件 ID 1074 显示 MoNotificationUx.exe(Windows Update 协调程序)或其他计划重启原因。
修复方法:等待 PC 完成启动,然后重新连接。要避免再次发生,请在 Windows Update 设置中设置活动时间/禁用活动时间内自动重启,或安排在用户不使用计算机时重启。
如果你有管理员权限,可使用 Get-CimInstance Win32_OperatingSystem 获取 LastBootUpTime,并使用 Get-WinEvent 查询事件 ID 1074。有关 WSL/SSH 编码命令技巧,请参阅 references/direct_pc_and_auth_diagnostics.md。
第 5 步:验证修复
应用修复后,重新连接并验证相应症状:
对于 AVD/WVD/W365:
- 查看“连接信息”——传输协议应显示为
UDP或UDP Multicast。 - RTT 应显著降低(例如,从 165ms 降至 40-60ms)。
- 使用 lsof 验证:
lsof -i UDP -n -P 2>/dev/null | grep -i "Windows"
# Should show UDP connections if Shortpath is active
对于 Direct PC:
- 进度对话框应消失,且会话窗口应显示。
- 新会话的 Windows App 日志应显示鼠标/键盘输入事件(
IHAddMouseEventToPDU、IHAddKeyboardEventToPDU),且没有UserCancelled(8)错误。 - 如果问题由已过期的 Microsoft 账户导致,请确认 Windows App →“设置”→“账户”中只保留有效账户。
对于服务器重启:
- 使用
ping和scripts/probe_rdp_server.py验证 PC 是否重新可访问。 - 确认
LastBootUpTime是最近的,且与服务中断时段相符。
参考资料
- references/windows_app_log_analysis.md — 详细的日志解析模式、错误特征、GUID 生命周期分析和比较方法
- references/avd_transport_protocols.md — AVD 传输选择的工作方式、STUN/TURN/ICE 概述、Shortpath 架构
- references/direct_pc_and_auth_diagnostics.md — Direct PC 连接失败、已过期 Microsoft 账户导致的问题、RDP 协议探测器用法、Windows 端重启关联分析、卡住的对话框与活动会话的区分
- scripts/probe_rdp_server.py — 独立的 RDP 协议和 TLS 健康状况探测工具