CoreAudio是唯一靠谱方案,因WASAPI/KS音频会话无法通过进程枚举或注册表识别,必须用IAudioSessionManager2获取活跃会话并调用IAudioSessionControl2.GetProcessId;需STA线程、延迟枚举、异常捕获及双校验确保健壮性。

为什么 CoreAudio 是唯一靠谱的方案
Windows 系统层面的声音播放进程,无法靠 Process.GetProcesses() 或注册表扫描识别——因为绝大多数音频输出走的是 WASAPI 或 Kernel Streaming,进程本身不暴露“我在播声音”这种状态。只有通过 Windows Core Audio APIs(即 IAudioSessionManager2 和 IAudioSessionEnumerator)才能拿到当前活跃的音频会话,进而反查归属进程 ID。
别试 WaveInGetNumDevs、DirectSound 或轮询 GetForegroundWindow,它们要么只管输入、要么早已过时、要么和声音播放完全无关。
- 必须用 COM 互操作调用,C# 需引用
CoreAudioApi.dll(推荐 NuGet 包CoreAudioApi,非微软官方但封装干净) - 调用前必须在 STA 线程执行(
[STAThread]主函数或Thread.SetApartmentState(ApartmentState.STA)) - 需要
MMDeviceEnumerator获取默认渲染设备,再获取其AudioSessionManager2
ISimpleAudioVolume 和 IAudioSessionControl2 到底该用哪个
两者都来自同一音频会话对象,但职责不同:ISimpleAudioVolume 只管音量/静音状态;IAudioSessionControl2 才能拿到进程 ID(GetProcessId)、显示名(GetDisplayName)、是否已销毁(State == AudioSessionState.ASS_ACTIVE)。
常见错误是只遍历 ISimpleAudioVolume 却漏掉进程信息,结果只能看到“有音量”,但不知道是谁在播。
- 必须先 QueryInterface 到
IAudioSessionControl2才能安全调用GetProcessId - 某些系统服务(如 Windows Audio Device Graph Isolation)会创建会话但无对应用户进程,
GetProcessId返回 0,需过滤 -
GetDisplayName在多数第三方应用中为空,别依赖它判断应用身份,优先用进程 ID +Process.GetProcessById()查名称
为什么刚启动就拿不到活跃会话?
不是代码写错了,是音频会话有延迟激活机制:应用调用 IAudioClient::Initialize 后,会话不会立刻出现在枚举器里,通常要等第一次实际数据提交(IAudioRenderClient::ReleaseBuffer)之后才注册。所以启动监控后立即遍历,大概率为空。
- 加个 500ms 延迟再首次枚举(
Task.Delay(500)),比轮询更稳 - 真正健壮的做法是监听
OnSessionCreated事件(通过IAudioSessionNotification),但注意该回调也在 STA 线程触发,不能直接更新 UI 控件 - 部分 UWP 应用(如 Xbox Game Bar 录制组件)会话类型为
AudioSessionGroupingParam,GetProcessId返回 0,需用GetGroupingParam+ 关联逻辑识别
获取到进程 ID 后,怎么避免 System.ArgumentException: No process is associated with this object
音频会话生命周期长于进程——进程退出后,会话可能还在销毁队列里,此时 GetProcessId 仍返回旧值,但 Process.GetProcessById() 已失效。
- 务必用
try/catch (ArgumentException)包裹Process.GetProcessById()调用 - 更轻量的验证方式:调用
OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, ...)(P/Invokekernel32.dll),比新建Process实例快且不抛异常 - 不要缓存
Process对象,每次需要时重新获取,避免句柄泄漏或状态过期
音频会话状态同步不是实时的,尤其在快速启停多个播放器时,两次枚举之间可能有 100–300ms 不一致窗口。别指望“绝对精确”,重点是把住 ASS_ACTIVE 状态 + 进程存活双校验。


















