Files
Cyrene_v2/internal/runtime/voice/ttslaunch/proc_windows.go
T
AskaEth 6906d274fc feat(voice): M47 后端启动后探活 emotionTTS,未起则异步拉起一键启动脚本
主人 2026-10-24:「tts启动脚本在这 ...\一键启动.bat,以后启动后端可以顺便检测
一下如果TTS没起就顺带启一下」。本片只做「启动时顺带探一下」,**默认关**(主人
早前说过「开机自启先不急 后面做」),未开开关时连探活都不发。

- 新包 internal/runtime/voice/ttslaunch:探 http://127.0.0.1:9880(毫秒级超时),
  已在跑什么都不做;没起则异步起脚本(cmd.exe /c 传参,不拼命令行字符串)
- 防重复:in-flight 单飞 + 一次尝试后的冷却(失败也算一次,重启风暴不会变成重试风暴)
- 失败只 WARN:探活超时/脚本不存在/起进程失败都只记带 source 的日志,
  组合根那条路径**没有 error 通道**
- 配置走面板文件 $DATA_DIR/config/voice-tts-launch.json(零新 .env 键)
- 接线在 cmd/cyrene 的网关 Listen 之后,整段在后台 goroutine 里,不占启动时长
  (用例以「挂载耗时 < 150ms 而探活超时 800ms」证明)
- 不新开端点、不加帧族;不碰 gateway 包
2026-10-26 18:47:36 +08:00

36 lines
1.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//go:build windows
package ttslaunch
import (
"os/exec"
"syscall"
)
const (
// createNewProcessGroup 让子进程成为**新进程组**的组长:后端控制台里的 Ctrl+C
// 只送给后端自己的进程组,不会连带掐掉 TTS。
createNewProcessGroup = 0x00000200
// createNewConsole 给子进程开**自己的**控制台窗口 —— 与主人「双击一键启动.bat」
// 看到的形态一致(TTS 的日志照常可见,不糊进后端日志),也不受后端控制台关闭影响。
createNewConsole = 0x00000010
)
// shellCommand 构造「解释一个批处理文件」的命令。
//
// 为什么必须经 cmd.exe:`.bat` 不是 PE 可执行映像,Windows 内核无法直接
// CreateProcess 起来(要么失败,要么依赖某个 Go 版本碰巧的兼容路径)。这里把脚本
// 路径作为**独立参数**交给 exec.Command —— 绝不自己拼命令行字符串,空格/中文路径
// 的引号由 os/exec 按 Windows 规则处理(主人那个路径含中文,也见过含空格的安装路径)。
func shellCommand(script string) *exec.Cmd {
return exec.Command("cmd.exe", "/c", script)
}
// startDetached 以"脱离后端生命周期"的方式起进程(不接管它的输入输出)。
func startDetached(cmd *exec.Cmd) error {
cmd.SysProcAttr = &syscall.SysProcAttr{
CreationFlags: createNewProcessGroup | createNewConsole,
}
return cmd.Start()
}