Skip to content

Windows: 服务模式下终端立即退出 - 综合修复方案 #22

@baichayo

Description

@baichayo

Bug Report

环境信息

  • rtty-go 版本: v1.1.1 (commit a2394c5)
  • 操作系统: Windows 10/11
  • 运行模式: 服务模式(非交互式会话)
  • Go 版本: 1.24.4

问题描述

在 Windows 服务模式下,终端会话启动后立即退出(通常在 100ms 内)。

症状

  • ✅ cmd.exe 能够启动并显示命令提示符
  • ❌ 但随即立即退出,导致连接断开
  • ❌ 用户无法输入任何命令

复现频率:服务模式下必现


根本原因分析

经过深入调查,确认了多个相互关联的根本原因

1. ConPTY 库缺陷(主要问题)

当前使用的 github.com/qsocket/conpty-go 库存在关键缺陷:

  • ❌ 未设置 STARTF_USESTDHANDLES 标志
  • ❌ 未将标准句柄初始化为 NULL
  • ❌ 维护状态不佳(2023-03-15 后无更新)

影响

服务模式运行时:
1. 父进程 stdin/stdout 被重定向到管道/文件
2. 子进程(cmd.exe)继承父进程的重定向句柄
3. cmd.exe 尝试从父进程 stdin 读取而非 PTY
4. 遇到 EOF/Broken Pipe(错误码 0xC0000142)
5. 立即退出

2. 初始化稳定性问题

  • ❌ 缺少初始窗口大小设置,某些 Windows 版本的零尺寸导致退出
  • ❌ 并发控制机制存在死锁风险

3. Shell 启动问题

  • ❌ 硬编码 "cmd.exe" 路径
  • ❌ 缺少 /D /Q 参数,受 AutoRun 脚本干扰
  • ❌ 缺少进程退出日志

综合修复方案

本 PR 提供了经过验证的完整解决方案,包含所有必要的修复:

修复 1:切换 ConPTY 库

  • qsocket/conpty-go 切换到 UserExistsError/conpty v0.1.4
  • ✅ 显式设置 STARTF_USESTDHANDLES
  • ✅ 标准句柄初始化为 NULL
  • ✅ 正确的句柄生命周期管理
  • ✅ 专为非交互式/重定向上下文设计

修复 2:初始化稳定性改进

  • ✅ 添加 closed 标志防止 WaitAck 死锁
  • ✅ 使用 Broadcast() 替代 Signal() 唤醒所有等待者
  • ✅ 设置初始窗口大小 pty.Resize(80, 24)

修复 3:Shell 启动参数优化

  • ✅ 使用 COMSPEC 环境变量定位系统 shell
  • ✅ 添加 /D /Q 参数跳过 AutoRun 脚本
  • ✅ 记录进程退出代码便于调试

修改文件

  • go.mod: 依赖库切换
  • go.sum: 依赖校验和
  • rtty.go: 日志上下文改进
  • terminal_windows.go: 所有修复实现

测试验证

测试环境

  • 操作系统:Windows 10/11
  • 运行模式:服务模式(关键测试场景)

测试结果

场景 修复前 修复后
服务模式 ❌ 立即退出 ✅ 稳定运行
控制台模式 ✅ 正常 ✅ 正常
长期稳定性 ❌ 会话存活 < 1s ✅ 长期稳定

影响范围

  • 平台: 仅 Windows(terminal_windows.go, rtty.go
  • 向后兼容: ✅ 完全兼容
  • API 变更: 无
  • 依赖变更: 1 个库替换

风险控制

  1. 版本固定: UserExistsError/conpty v0.1.4
  2. 回滚计划: 单行 go.mod revert 即可回退
  3. 验证 commit: 8450f99(已在生产环境验证)

相关 Issues

本 Issue 综合并替代以下分散的 Issues:

相关 PRs

本 PR 综合并替代以下分散的 PRs:


经过充分测试验证,建议优先审查。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions