SoundSwitch CLI 命令行工具完全指南:开关音频设备、管理麦克风静音与配置文件
SoundSwitch CLI 命令行工具完全指南:开关音频设备、管理麦克风静音与配置文件
SoundSwitch 是一款用于切换 Windows 默认播放/录音设备的 C# 桌面应用,而 SoundSwitch.CLI 是它的官方命令行接口,让用户无需打开图形界面即可完成设备切换、麦克风静音控制、配置文件管理与状态查询。本文将以 CLI 官方文档为主体,结合仓库源码深入讲解全部命令、参数、JSON 输出约定与底层 IPC 通信原理,读完即可在脚本、自动化任务中熟练驾驭 SoundSwitch。
概览:CLI 的定位与工作方式
SoundSwitch CLI 是一个独立的控制台程序,它本身不直接操作音频设备,而是通过 Windows 命名管道(Named Pipe)向正在运行的 SoundSwitch 主程序发送控制消息,由主程序代为执行真正的设备切换与状态查询。这意味着使用 CLI 前通常需要 SoundSwitch 主程序处于运行状态。
从 SoundSwitch.CLI.csproj 可以看出:
- 目标框架为
net10.0,支持 Debug / Release / Beta / Nightly 多种构建配置; - 直接引用 SoundSwitch.IPC 项目,所有命令的请求/响应都经由 IPC 层完成;
- 使用
Spectre.Console.Cli解析命令行参数、Spectre.Console渲染表格与进度状态,并用MessagePack在管道中做二进制序列化。
命令入口定义在 Program.cs:通过 CommandApp 注册了 switch、profile、settings、mute、status、devices 六个子命令,并附带各自的示例用法。
全局约定:--json 与退出码
所有命令都接受 --json 选项,用于输出机器可读的 JSON。该选项由公共基类 JsonCommandSettings 统一注册,各命令继承即可自动获得。
- 成功时输出业务 JSON 并以退出码 0 结束;
- 失败时统一输出一个包含
error字段的 JSON 对象,并以退出码 1 结束:
{ "error": "Failed to retrieve status" }
JSON 输出统一由 JsonOutput 负责,它使用带缩进的 JsonSerializer 直接写入 Console.Out。源码注释特别强调:JSON 模式下绝不能使用 Spectre.Console 的进度动画或标记语法,因为它们会输出 ANSI 转义序列,污染管道输出——因此 --json 的结果可以安全地交给 jq 解析或捕获到变量中。
命令详解
switch:切换播放/录音设备
切换默认播放或录音设备,在 SoundSwitch 已选定的设备列表中循环:
SoundSwitch.CLI.exe switch --type Recording
SoundSwitch.CLI.exe switch --type Playback
SoundSwitch.CLI.exe switch --type Playback --json
参数 --type(等价写法 -t,也支持位置参数)取值对应 IPC 层的 AudioType 枚举,常用值为 Playback(播放)与 Recording(录音)。成功时输出 { "success": true, "type": "Playback" }:
{
"success": true,
"type": "Playback"
}
从 SwitchCommand.cs 的实现看,该命令构造 TriggerSwitchRequest { Type = settings.Type } 并经 NamedPipe.SendRequestAsync<TriggerSwitchResponse> 发送,只有响应 Success 为真才返回 0,否则输出 { "error": "Failed to switch ... device" } 并返回 1。非 JSON 模式下会显示一个带旋转动画的状态提示 Switching Playback device...,成功显示绿色提示,失败显示红色提示。
mute:麦克风静音控制
查询与设置默认麦克风的静音状态:
SoundSwitch.CLI.exe mute # 显示当前静音状态
SoundSwitch.CLI.exe mute --state true # 静音麦克风
SoundSwitch.CLI.exe mute -s false # 取消静音
SoundSwitch.CLI.exe mute --toggle # 切换静音状态
SoundSwitch.CLI.exe mute --json # 以 JSON 查询当前状态
参数说明:
| 参数 | 等价写法 | 说明 |
|---|---|---|
--state |
-s |
布尔值 true/false,指定目标静音状态 |
--toggle |
-t |
将当前状态取反(切换) |
| 不传任何参数 | — | 仅查询并显示当前状态 |
注意 --state 的类型是可空布尔(bool?):不传时仅查询。--json 变体总是输出 { "deviceName": "...", "isMuted": true|false }:
{
"deviceName": "Microphone (USB Audio Device)",
"isMuted": false
}
MuteCommand.cs 的实现揭示了它的智能逻辑:
- 先发送
MicrophoneStateRequest查询当前状态; - 若未指定
--state且未指定--toggle,直接输出当前状态并返回 0; - 计算目标状态(
--toggle时取当前值反相,否则取--state的值); - 若目标状态与当前一致,不做任何修改,直接输出当前状态(幂等);
- 否则发送
MuteRequest { Mute = targetState }执行变更。
这一设计保证重复执行 mute --state true 不会产生无意义的管道往返。若系统没有设置默认麦克风,或主程序无法响应,命令会以退出码 1 报错。
profile:配置文件管理
配置文件(Profile)是 SoundSwitch 将一组播放/录音设备绑定到某个场景(如游戏、会议)的功能。CLI 支持列出全部配置和触发指定配置。
列出所有可用配置文件:
SoundSwitch.CLI.exe profile --list
SoundSwitch.CLI.exe profile --list --json
--list(等价写法 -l)的 JSON 输出是一个配置文件对象数组,每个对象包含 name、playbackDevice、playbackCommunicationDevice、recordingDevice、recordingCommunicationDevice 五个字段:
[
{
"name": "Gaming",
"playbackDevice": "Speakers (Realtek(R) Audio)",
"playbackCommunicationDevice": "Headset Earphone (HyperX Cloud II)",
"recordingDevice": "Microphone (USB Audio Device)",
"recordingCommunicationDevice": "Headset Microphone (HyperX Cloud II)"
}
]
触发(激活)指定配置文件:
SoundSwitch.CLI.exe profile --name "Profile Name"
--name(等价写法 -n)配合 --json 时,成功输出 { "success": true, "profile": "Profile Name" }:
{
"success": true,
"profile": "Gaming"
}
ProfileCommand.cs 的校验逻辑:若未指定 --list 且 --name 为空,直接输出 { "error": "Profile name is required unless --list is specified" } 并返回 1。非 JSON 模式下 --list 渲染为五列表格(Profile / Playback / Playback Comm / Recording / Recording Comm),绿色标识播放类设备、红色标识录音类设备。
settings:打开设置窗口
在 GUI 中打开 SoundSwitch 设置窗口:
SoundSwitch.CLI.exe settings
SoundSwitch.CLI.exe settings --json
JSON 输出为:
{
"success": true
}
实现上发送 OpenSettingsRequest,成功返回 0;失败输出 { "error": "Failed to open settings" } 并返回 1。
status:查询当前状态
显示当前激活的配置文件与默认音频设备:
SoundSwitch.CLI.exe status # 人类可读的表格输出
SoundSwitch.CLI.exe status --json # 机器可读的 JSON 输出
JSON 输出包含五个字段:activeProfile、playbackDevice、recordingDevice、playbackCommunicationDevice、recordingCommunicationDevice。不存在的设备序列化为空字符串 "":
{
"activeProfile": "Gaming",
"playbackDevice": "Speakers (Realtek(R) Audio)",
"recordingDevice": "Microphone (USB Audio Device)",
"playbackCommunicationDevice": "Headset Earphone (HyperX Cloud II)",
"recordingCommunicationDevice": "Headset Microphone (HyperX Cloud II)"
}
重要语义说明: “Active Profile” 显示的是最后一次由用户操作或触发规则显式激活的配置文件,它不会反映 SoundSwitch 之外对系统的更改(例如直接在 Windows 声音设置里切换设备)。因此脚本在判断“当前生效配置”时应理解这一限制。表格式输出中,无激活配置时 activeProfile 显示为 None。
devices:列出可切换设备
列出当前在线且在 SoundSwitch 设置中被选中的设备(即 SoundSwitch 循环切换时会用到的设备集合):
SoundSwitch.CLI.exe devices
SoundSwitch.CLI.exe devices --json
JSON 输出为 { "playbackDevices": [...], "recordingDevices": [...] }:
{
"playbackDevices": [
"Speakers (Realtek(R) Audio)",
"Headset Earphone (HyperX Cloud II)"
],
"recordingDevices": [
"Microphone (USB Audio Device)"
]
}
注意该命令与 status 的区别:status 报告当前正在使用的默认设备,devices 报告 SoundSwitch 切换时会遍历的设备集合。实际返回内容由 DevicesCommand.cs 通过 GetSwitchableDevicesRequest 从主程序获取。
实战示例
以下 8 个示例覆盖了 CLI 的典型使用场景,可直接复制到 PowerShell / CMD / 批处理脚本中:
# 1. 切换到下一个播放设备
SoundSwitch.CLI.exe switch --type Playback
# 2. 切换到下一个录音设备
SoundSwitch.CLI.exe switch --type Recording
# 3. 列出所有可用配置文件
SoundSwitch.CLI.exe profile --list
# 4. 触发指定配置文件
SoundSwitch.CLI.exe profile --name "Headphones + Mic"
# 5. 打开设置窗口
SoundSwitch.CLI.exe settings
# 6. 静音/取消静音麦克风
SoundSwitch.CLI.exe mute -t # 切换静音状态
SoundSwitch.CLI.exe mute -s true # 静音
SoundSwitch.CLI.exe mute --state false # 取消静音
# 7. 查看当前音频状态
SoundSwitch.CLI.exe status
SoundSwitch.CLI.exe status --json
# 8. 列出选中用于切换的设备
SoundSwitch.CLI.exe devices
SoundSwitch.CLI.exe devices --json
与 jq 组合可写出更智能的自动化逻辑,例如:
# 只有当前激活配置不是 Gaming 时才切换到 Gaming
if [ "$(SoundSwitch.CLI.exe status --json | jq -r '.activeProfile')" != "Gaming" ]; then
SoundSwitch.CLI.exe profile --name "Gaming"
fi
错误处理
CLI 在以下场景会给出明确报错(均以退出码 1 结束):
- SoundSwitch 主程序未运行:管道客户端在 5 秒连接超时(
CONNECTION_TIMEOUT,见 NamedPipe.cs)内无法连上命名管道; - 配置文件名称无效:
profile --name指定的名称在主程序中不存在,或未提供名称且未加--list; - 连接问题:管道连接中断、响应超时或服务端返回
ErrorResponse; - 无效命令或选项:Spectre.Console.Cli 会拒绝未注册的命令与非法参数值;
- 未设置默认麦克风(仅影响
mute命令):无法确定要查询/操作的目标设备。
所有命令均支持 --help 查看完整的参数说明与示例:
SoundSwitch.CLI.exe switch --help
SoundSwitch.CLI.exe --help
底层原理:IPC 管道与 MessagePack
CLI 的全部能力依赖 SoundSwitch.IPC 提供的命名管道基础设施,理解它有助于排查“CLI 无响应”类问题。
管道命名规则: PipeConstants.cs 定义管道名为 "SoundSwitch" + Environment.UserName,即按 Windows 用户名区分,同一用户会话下的主程序与 CLI 共用同一条管道。
消息协议: NamedPipe.cs 的 SendRequestAsync 是 CLI 所有命令的公共调用链:
- 创建/复用
NamedPipeClientStream并连接(超时 5 秒); - 用 MessagePack 序列化请求对象,先写入 4 字节长度前缀再写入负载;
- 读取响应长度(上限 1 MiB),按长度读取并反序列化;
- 若收到
ErrorResponse,抛出PipeRequestException,命令层捕获后转为 JSON 错误输出。
每个 CLI 命令与对应的 IPC 消息一一对应:switch → TriggerSwitchRequest(TriggerSwitchRequest.cs)、profile --list → GetProfileListRequest、status → GetActiveDevicesRequest、devices → GetSwitchableDevicesRequest、mute → MicrophoneStateRequest/MuteRequest、settings → OpenSettingsRequest,请求对象均带 [MessagePackObject(keyAsPropertyName: true)] 特性以属性名作为键。
由于采用了长度前缀 + MessagePack 的紧凑协议,CLI 的每次交互只产生几百字节到几 KB 的管道流量,非常轻量,适合高频调用。若主程序 15 秒内未响应,客户端会抛出超时异常并重建连接(见 NamedPipe.cs)。
适用前提与限制
- 平台:SoundSwitch 是 Windows 专属应用,CLI 依赖
System.IO.Pipes命名管道与 Windows 音频栈,仅在 Windows 上运行; - 前置条件:使用前需构建或安装 CLI,并确保 SoundSwitch 主程序正在运行;
- 配置联动:
switch与devices的行为受 SoundSwitch 设置中“已选中设备”的影响——只有被选中的在线设备才会参与循环切换; - 状态语义:
status的activeProfile反映的是 SoundSwitch 内部记录的最近一次显式激活,不代表系统层面未经 SoundSwitch 干预的实时设备状态。
掌握以上命令与语义,你就可以把 SoundSwitch 无缝接入自己的脚本、快捷键工具或自动化工作流,实现一键切换耳机/音箱、会议前自动静音麦克风等场景。