BeyondDimension / BeyondDimension/SteamTools
🐛[BUG] -clt proxy / -clt shutdown 对运行中的实例无响应,冷启动也不会按注释拉起程序
- Dominant language
- C#
- Stars
- 26.8k
- Forks
- 1.7k
- PR merge metrics
- No merged PRs in 30d
Description
## 请认真检查以下清单中的每一项
- [X] 已经搜索过,没有发现类似的 issue
- [X] 已经搜索过文档,没有发现相关内容
- [X] 已经尝试使用过最新版,问题依旧存在
- [X] 使用的是官方版本(未替换及修改过安装目录程序文件)
### 🐛 描述
`src/BD.WTTS.Client/Startup/Startup.Commands.cs` 里有 `proxy` 命令,注释写的是「启用代理服务,静默启动(不弹窗口)」,另有 `-clt shutdown`(安全结束正在运行的程序)。常量在 `Startup.Constants.cs`(`clt_ = "-clt"`、`key_proxy = "proxy"`、`key_shutdown = "shutdown"`、`key_show = "show"`),服务端分支在 `Startup.Host.cs` 的 `case key_proxy` → `IProxyService.StartOrStopProxyService(bool)`。本机 Windows x64 3.1.0 安装目录里能搜到「启用代理服务,静默启动(不弹窗口)」这串字面量,所以应当是带这个功能的版本。
实测三点:
1. **有实例在跑时,命令送达了但没有任何作用。** 客户端退出码 0,而三项外部判据全部不变:hosts 里的 `# Steam++ Start` 段、443 的监听者(`Steam++.Accelerator`)、`curl -I https://github.com/` 的返回码。当天日志 `%Tmp%\Steam++\Logs\nlog-all-2026-09-12.log` 是跨实例连续追加的同一个文件,**21:56:33 之后直到 23:01:03 之间零新增行**,而这段时间内我投了 6 次 `-clt proxy` 各种写法与 1 次 `-clt shutdown`。也就是说主实例侧既没有成功日志也没有失败日志。
2. **没有实例在跑时,`-clt proxy -on` 不会把程序拉起来。** 客户端 1s 内退出(码 0),连续轮询 36s 进程数为 0、hosts 不变。按 `Startup.Commands.cs` 的注释这条路应当走「未启动 → 类似 `-silence` 逻辑」。
3. 中途一次 `-clt proxy -on` 之后进程数从 3 变 4 且未回收(我没能区分那是第二个完整实例还是子进程,不敢断言)。
顺带一个容易误伤使用者的点:不带任何参数启动时,`Startup.SingleInstancePipeline.cs:18` 是
`SendMessage(sendMessage?.Invoke() ?? (IsMainProcess ? key_show : ""))`,默认消息就是 `key_show`,
所以「想用命令行静默开启」而直接执行 `Steam++.exe`(不带 `-clt`)必然把主窗顶到前台。这本身是设计如此,但和 `proxy` 命令注释放在一起时很容易被当成同一条路。
### 📷 复现步骤
前置:正常启动程序并开启网络加速,确认 hosts 有 `# Steam++ Start` 段、`Get-NetTCPConnection -State Listen -LocalPort 443` 的持有者是 `Steam++.Accelerator`。
1. 执行 `Steam++.exe -clt proxy -off true`,等 20s
2. 复看上面三项判据 —— 本机全部不变,且当天日志零新增行
3. 把程序完全退出(管理员 `Stop-Process`,见下方补充),再执行 `Steam++.exe -clt proxy -on`,等 40s
4. 复看进程数与 hosts —— 本机为 0 进程、无变化
参数写法已排除是我语法错(用退出码当解析探针,`bogus-verb` 给 1 作对照):
| 参数 | 客户端退出码 | 主实例反应 |
| --- | --- | --- |
| `-clt proxy --off` | 1(解析失败) | 无 |
| `-clt proxy -off true` | 0 | 无 |
| `-clt proxy -off` | 0 | 无 |
| `-clt proxy`(想 toggle) | 0 | 无(`case key_proxy` 要求 `args.Length >= 2`,按源码本来就不该有反应) |
| `-clt shutdown` | 0 | 无 |
| `-clt bogus-verb` | 1(对照组) | — |
### 📄 日志信息
另一个观察:**每次开启加速都会刷 7~8 条同名异常,但加速最终仍然成功**。下面两段的栈逐字相同,前者来自 GUI 手点(与 hosts 修改时间 21:56:34 吻合),后者来自命令行冷启动(23:13:24,另一次 23:01:03、23:05:20、23:07:27 各一组,条数 7~8 条):
```
2026-09-12 23:13:24.7772|Error|StartOrStopProxyService|System.Threading.Tasks.TaskCanceledException: A task was canceled.
---> System.Threading.Tasks.TaskCanceledException: A task was canceled.
at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(...)
at System.Net.Http.RedirectHandler.SendAsync(...)
at System.Net.Http.SocketsHttpHandler.g__CreateHandlerAndSendAsync|115_0(...)
at System.Net.Http.HttpClient.g__Core|83_0(...)
--- End of inner exception stack trace ---
at System.Net.Http.HttpClient.HandleFailure(...)
at BD.WTTS.Services.Implementation.NetworkTestService.TestDNSOverHttpsAsync(String testDomain, String dohServer, DnsRecordType dnsRecordType, CancellationToken cancellationToken)
at BD.WTTS.Services.ProxyService.GetValidDNSAsync(String dns, CancellationToken cancellationToken) |
```
想确认这是 `ProxyBeforeDNSCheck` 的预期日志(DoH 探测失败按 Error 记账)还是异常路径。若属预期,建议这几条降级到 Debug 或补一条「哪个 dns、超时多少」的可读信息:自动化侧要靠日志判断「这次到底成没成」,现在只能退回去看 hosts 段和 443 的持有者。
### 🖼 截图
不放截图,避免把本机窗口标题和账号信息带出去;上面三项判据都能命令行复验,比图更省事。
### 🚑 其他信息
- 处理器体系结构:x64
- 系统版本号:Windows 11 专业版 25H2 Build 26200
- 下载渠道:本机安装在自定义目录(不是微软商店路径),具体渠道我无法从安装产物反推
- 程序版本:3.1.0(FileVersion 3.1.2025.0,`releases/latest` 也是 3.1.0)
- 是否包含独立运行时:否(安装目录内未见 hostfxr / hostpolicy)
补充一个绕法现状,也是提这个 issue 的原因:我这边「自动开」最后是绕到 **冷实例 + `ProgramStartupRunProxy=true`** 实现的(实测约 6s 起效,且 `MainWindowHandle=0`、不抢前台);但「自动关」没有优雅路径 —— 只能管理员 `Stop-Process`,而**被杀掉的实例不会还原 hosts**(本机实测留下 47 条 `127.0.0.1` 僵尸行,此时 GitHub 直接 `curl` 000),所以还得自己按 `# Steam++ Start` / `# Steam++ End` 标记把段剥掉,并且 hosts 在刚杀完会被短暂锁住、写入要重试。`CloseMainWindow()` 也不算退出路径,它只是缩进托盘、hosts 照旧。
如果 `-clt proxy -off` 与 `-clt shutdown` 能对运行中的实例正常响应,这两件事就都能优雅收口,也就没有必要用「杀进程 + 清 hosts」这种脏办法。
同源、都还 open 的几条相关 issue(现象不同,但都是「启动路径上的窗口/权限」这一类):#3805(每次启动都弹 UAC)、#2004(自启动强制最小化不生效)、#3650(开机弹窗)、#3316(开机自动加速遇 hosts 掉权限会反复弹网页)。
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with src/BD.WTTS.Client/Startup/Startup.Commands.cs and follow the proxy and shutdown paths through Startup.Host.cs, Startup.Constants.cs, and Startup.SingleInstancePipeline.cs. Reproduce the listed -clt commands on Windows while checking the process, hosts markers, port 443 listener, and logs. Done means running instances respond, cold-start proxy works as documented, and shutdown exits cleanly without leaving hosts entries behind.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- cli, desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100