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

如何使用C++/WinRT通过Windows.Media.Control获取当前运行媒体会话信息

核心问题说明

你当前的代码无法运行的根本原因是:GlobalSystemMediaTransportControlsSessionManager 没有公开可直接调用的构造函数,不能像普通C++类一样直接栈上构造实例,必须通过类提供的静态异步方法RequestAsync()获取已初始化的管理器对象,之后才能调用GetSessions()枚举会话。

实现步骤
  • 配置项目环境:确保项目已经正确引用对应版本Windows SDK的WinRT元数据,在代码文件中引入必要头文件
  • 异步获取会话管理器实例:所有WinRT异步API必须在协程中通过co_await调用,禁止同步阻塞等待避免死锁
  • 枚举会话列表读取属性:拿到管理器实例后即可获取当前所有活跃媒体会话,遍历读取每个会话的应用标识、播放状态、媒体元数据等信息
  • (可选)注册变更监听:如果需要实时感知会话启动/退出,可以注册SessionsChanged事件自动刷新列表
可运行示例代码
#include <winrt/Windows.Media.Control.h>
#include <winrt/Windows.Foundation.Collections.h>
using namespace winrt::Windows::Media::Control;
using namespace winrt::Windows::Foundation::Collections;

// 协程函数,按需在你的业务逻辑中调用
winrt::Windows::Foundation::IAsyncAction LoadAllActiveMediaSessions()
{
    // 异步获取初始化完成的会话管理器
    GlobalSystemMediaTransportControlsSessionManager sessionManager =
        co_await GlobalSystemMediaTransportControlsSessionManager::RequestAsync();

    // 拉取当前所有活跃媒体会话
    IVectorView<GlobalSystemMediaTransportControlsSession> sessions = sessionManager.GetSessions();

    // 遍历会话读取信息
    for (auto const& session : sessions)
    {
        // 获取会话所属应用的AUMID,可用于映射应用名称
        winrt::hstring sourceAppId = session.SourceAppUserModelId();
        
        // 读取播放状态
        GlobalSystemMediaTransportControlsSessionPlaybackInfo playbackInfo = session.GetPlaybackInfo();
        auto playbackStatus = playbackInfo.PlaybackStatus();

        // 读取当前播放媒体的元数据(标题、艺术家、专辑等)
        auto mediaProperties = co_await session.TryGetMediaPropertiesAsync();
        if (mediaProperties)
        {
            winrt::hstring trackTitle = mediaProperties.Title();
            winrt::hstring trackArtist = mediaProperties.Artist();
            // 按需处理获取到的媒体信息
        }
    }

    // 注册会话列表变更监听,会话新增/移除时自动触发
    sessionManager.SessionsChanged([](
        GlobalSystemMediaTransportControlsSessionManager const& sender,
        winrt::Windows::Foundation::IInspectable const& /*args*/)
    {
        // 重新拉取最新会话列表即可
        IVectorView<GlobalSystemMediaTransportControlsSession> updatedSessions = sender.GetSessions();
        // 处理更新后的列表
    });
}
注意事项
  • 线程要求:调用RequestAsync()时需要当前线程为MTA(多线程单元),如果在UI线程(STA)调用,请确保C++/WinRT单元环境已正确初始化,否则会抛出调用失败异常。
  • 空值处理:部分处于启动/退出过程中的会话,调用TryGetMediaPropertiesAsync()可能返回空值,必须增加判空逻辑避免访问空指针崩溃。
  • 权限说明:该API不需要额外在应用清单中声明特殊能力,但仅能枚举当前用户会话下的非受保护媒体进程,开启DRM保护的媒体应用可能无法读取完整元数据,仅能获取基础应用标识。
  • 结果校验:调试时可以调出系统音量弹窗,弹窗中显示的活跃媒体会话就是该API能枚举到的全部会话,可直接对比校验结果是否正确。
学习建议
  • 先掌握C++/WinRT协程的基本使用规则,所有名称以Async结尾的WinRT API都需要通过co_await调用,不要尝试用get()等方法同步阻塞等待结果,极易造成UI线程死锁。
  • 调试阶段先只读取SourceAppUserModelId字段确认会话枚举正常,再逐步增加元数据读取、事件监听等逻辑,降低排错难度。
  • 如果需要把AUMID转换为用户可读的应用名称,可以通过PackageManager相关API根据AUMID查找应用对应的显示名。

内容的提问来源于stack exchange,提问作者MasiaSaig

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:01:15