You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下监听音频对象增删:C#是否存在可挂钩事件?

当然有靠谱的解决方案!你之前靠检测进程来追踪音量对象的思路确实容易踩坑——毕竟音频会话(也就是你说的「音量对象」)往往比进程创建晚一步,时间差问题会导致漏检。在C#里,我们可以直接监听Windows原生的Core Audio事件,完美解决这个问题。

在C#中监听Windows音频对象的添加/移除事件

核心思路是借助Windows的Core Audio API,它原生提供了音频会话的生命周期事件监听能力。为了简化C#中的调用,推荐使用成熟的.NET音频库NAudio,它已经封装了Core Audio的底层接口,不用自己写复杂的COM互操作代码。

一、快速实现步骤

1. 安装NAudio库

通过NuGet包管理器安装,或者在Package Manager Console中执行:

Install-Package NAudio

它支持.NET Framework、.NET Core及后续版本,兼容性拉满。

2. 编写监听代码示例

下面的代码可以直接监听音频会话的创建(对应音量对象添加)、销毁(对应音量对象移除),还能一次性获取当前所有活跃的音量对象列表(和Windows音量混合器一致):

using NAudio.CoreAudioApi;
using NAudio.CoreAudioApi.Interfaces;
using System;

public class AudioSessionMonitor : IAudioSessionNotification
{
    private AudioSessionManager2 _sessionManager;

    // 启动监听
    public void StartMonitoring()
    {
        var deviceEnumerator = new MMDeviceEnumerator();
        // 获取系统默认的播放设备(也可以指定其他设备)
        var defaultPlaybackDevice = deviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
        
        // 激活音频会话管理器
        _sessionManager = defaultPlaybackDevice.Activate(
            typeof(IAudioSessionManager2).GUID,
            CLSCTX.CLSCTX_ALL,
            null) as AudioSessionManager2;

        if (_sessionManager != null)
        {
            // 注册会话创建事件监听
            _sessionManager.RegisterSessionNotification(this);
            Console.WriteLine("已启动音频会话监听...");
            // 先获取当前所有活跃的音量对象
            PrintCurrentSessions();
        }
    }

    // 停止监听并释放资源
    public void StopMonitoring()
    {
        _sessionManager?.UnregisterSessionNotification(this);
        _sessionManager?.Dispose();
        Console.WriteLine("已停止音频会话监听");
    }

    // 监听新音频会话创建(音量对象添加)
    public void OnSessionCreated(IAudioSessionControl newSession)
    {
        var sessionControl = newSession as AudioSessionControl2;
        if (sessionControl != null && !sessionControl.IsSystemSoundsSession)
        {
            Console.WriteLine($"[新增音量对象] 进程名: {sessionControl.ProcessName} | PID: {sessionControl.ProcessId}");
            // 可以直接获取该会话的音量、静音状态
            var currentVolume = sessionControl.SimpleAudioVolume.Volume;
            Console.WriteLine($"  当前音量: {currentVolume:P} | 静音状态: {sessionControl.SimpleAudioVolume.Mute}");

            // 额外注册会话销毁事件
            sessionControl.OnSessionDisconnected += Session_OnSessionDisconnected;
        }
    }

    // 监听音频会话销毁(音量对象移除)
    private void Session_OnSessionDisconnected(object sender, SessionDisconnectedEventArgs e)
    {
        var sessionControl = sender as AudioSessionControl2;
        if (sessionControl != null)
        {
            Console.WriteLine($"[移除音量对象] 进程名: {sessionControl.ProcessName} | 原因: {e.DisconnectReason}");
        }
    }

    // 打印当前所有活跃的音量对象(对应音量混合器列表)
    private void PrintCurrentSessions()
    {
        Console.WriteLine("\n当前活跃音量对象列表:");
        var sessionEnumerator = _sessionManager.GetSessionEnumerator();
        foreach (var session in sessionEnumerator)
        {
            var sessionControl = session as AudioSessionControl2;
            if (sessionControl != null && !sessionControl.IsSystemSoundsSession)
            {
                Console.WriteLine($"- {sessionControl.ProcessName} (PID: {sessionControl.ProcessId})");
            }
        }
        Console.WriteLine("------------------------");
    }
}

// 调用示例
class Program
{
    static void Main(string[] args)
    {
        var monitor = new AudioSessionMonitor();
        monitor.StartMonitoring();

        Console.WriteLine("\n按任意键退出监听...");
        Console.ReadKey();
        monitor.StopMonitoring();
    }
}

二、方案优势

  • 无时间差问题:直接监听音频系统的原生事件,不会出现进程已创建但音频会话还未生成的漏检情况。
  • 信息完整:能获取音量对象的所有关键信息(进程名、PID、音量、静音状态等),完全匹配音量混合器的展示内容。
  • 覆盖全面:可以捕获所有类型的音频会话,包括那些没有独立进程的系统级音频(可通过IsSystemSoundsSession过滤)。

注意事项

  • 不需要管理员权限,普通用户权限即可获取大部分音频会话信息。
  • 记得在程序退出时调用StopMonitoring释放资源,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Albert MN.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:50:06