请认真检查以下清单中的每一项
🐛 描述
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 安装目录里能搜到「启用代理服务,静默启动(不弹窗口)」这串字面量,所以应当是带这个功能的版本。
实测三点:
- 有实例在跑时,命令送达了但没有任何作用。 客户端退出码 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。也就是说主实例侧既没有成功日志也没有失败日志。
- 没有实例在跑时,
-clt proxy -on 不会把程序拉起来。 客户端 1s 内退出(码 0),连续轮询 36s 进程数为 0、hosts 不变。按 Startup.Commands.cs 的注释这条路应当走「未启动 → 类似 -silence 逻辑」。
- 中途一次
-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。
- 执行
Steam++.exe -clt proxy -off true,等 20s
- 复看上面三项判据 —— 本机全部不变,且当天日志零新增行
- 把程序完全退出(管理员
Stop-Process,见下方补充),再执行 Steam++.exe -clt proxy -on,等 40s
- 复看进程数与 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.<SendAsync>g__CreateHandlerAndSendAsync|115_0(...)
at System.Net.Http.HttpClient.<SendAsync>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 掉权限会反复弹网页)。
请认真检查以下清单中的每一项
🐛 描述
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 安装目录里能搜到「启用代理服务,静默启动(不弹窗口)」这串字面量,所以应当是带这个功能的版本。实测三点:
# 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。也就是说主实例侧既没有成功日志也没有失败日志。-clt proxy -on不会把程序拉起来。 客户端 1s 内退出(码 0),连续轮询 36s 进程数为 0、hosts 不变。按Startup.Commands.cs的注释这条路应当走「未启动 → 类似-silence逻辑」。-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。Steam++.exe -clt proxy -off true,等 20sStop-Process,见下方补充),再执行Steam++.exe -clt proxy -on,等 40s参数写法已排除是我语法错(用退出码当解析探针,
bogus-verb给 1 作对照):-clt proxy --off-clt proxy -off true-clt proxy -off-clt proxy(想 toggle)case key_proxy要求args.Length >= 2,按源码本来就不该有反应)-clt shutdown-clt bogus-verb📄 日志信息
另一个观察:每次开启加速都会刷 7~8 条同名异常,但加速最终仍然成功。下面两段的栈逐字相同,前者来自 GUI 手点(与 hosts 修改时间 21:56:34 吻合),后者来自命令行冷启动(23:13:24,另一次 23:01:03、23:05:20、23:07:27 各一组,条数 7~8 条):
想确认这是
ProxyBeforeDNSCheck的预期日志(DoH 探测失败按 Error 记账)还是异常路径。若属预期,建议这几条降级到 Debug 或补一条「哪个 dns、超时多少」的可读信息:自动化侧要靠日志判断「这次到底成没成」,现在只能退回去看 hosts 段和 443 的持有者。🖼 截图
不放截图,避免把本机窗口标题和账号信息带出去;上面三项判据都能命令行复验,比图更省事。
🚑 其他信息
releases/latest也是 3.1.0)补充一个绕法现状,也是提这个 issue 的原因:我这边「自动开」最后是绕到 冷实例 +
ProgramStartupRunProxy=true实现的(实测约 6s 起效,且MainWindowHandle=0、不抢前台);但「自动关」没有优雅路径 —— 只能管理员Stop-Process,而被杀掉的实例不会还原 hosts(本机实测留下 47 条127.0.0.1僵尸行,此时 GitHub 直接curl000),所以还得自己按# Steam++ Start/# Steam++ End标记把段剥掉,并且 hosts 在刚杀完会被短暂锁住、写入要重试。CloseMainWindow()也不算退出路径,它只是缩进托盘、hosts 照旧。如果
-clt proxy -off与-clt shutdown能对运行中的实例正常响应,这两件事就都能优雅收口,也就没有必要用「杀进程 + 清 hosts」这种脏办法。同源、都还 open 的几条相关 issue(现象不同,但都是「启动路径上的窗口/权限」这一类):#3805(每次启动都弹 UAC)、#2004(自启动强制最小化不生效)、#3650(开机弹窗)、#3316(开机自动加速遇 hosts 掉权限会反复弹网页)。