如何根据XAudio2设备详细信息中的信息获取有关特定pnp扬声器的驱动程序信息

时间:2014-10-20 12:54:01

标签: c# audio wmi

我的系统插有两个PnP扬声器。它们都是同一类型的设备。一个安装在前面,一个安装在后面。可以让制造商添加一些驱动程序级别的ID,以便我们知道哪个是哪里。在设置播放的音频输出时,我需要能够确定从设备信息中查看哪个设备。

当我从XAudio2获取设备信息时:

var deviceCount = _xAudio2Instance.DeviceCount;

        for (int i = 0; i < deviceCount; i++)
        {
            var device = _xAudio2Instances.GetDeviceDetails(i);
            Console.WriteLine("Sound: {0},{1},{2}", device.DeviceId, device.DisplayName, device.Role);

给我一​​个输出:

Sound: {0.0.0.00000000}.{c55aa510-37ed-4139-a8bd-d0783eb07d5c},Speakers (Realtek High Definition Audio),11

Sound: {0.0.0.00000000}.{36cda8f6-e5b1-4c5f-877e-cf9b3a4a9ff7},Speakers (4- USB PnP Sound Device),DefaultCommunicationsDevice

Sound: {0.0.0.00000000}.{f562f43b-ba1f-489f-bf00-cf99e54a7513},Speakers (2- USB PnP Sound Device),NotDefaultDevice

我有以下属性: 设备编号 显示名称 输出格式 作用

对于两个设备,除了显示名称之外,一切都是相同的,显示名称将具有与该实例关联的数字编号。我们将安装许多这些设备,因此我无法保证这些数字是一致的。

我正在尝试将此设备实例与某个驱动程序级别值相关联,以便让我知道插入了什么物理设备。

然后我将在Win32_SoundDevice或类似的东西上使用一些WMI查询,但我找不到任何可以从XAudio2设备详细信息到Wmi声音设备实例的常用链接。

任何帮助将不胜感激。我知道它可以完成,因为我看到他们在Windows声音管理中做到了。

1 个答案:

答案 0 :(得分:0)

答案是您需要将设备ID映射到注册表,然后将注册表项映射到Win32_PnPSignedDriver条目:

首先从设备详细信息中获取设备ID:

var device = _xAudio2Instances[TchDevice.Core].GetDeviceDetails(i);
classId = device.DeviceId.Replace("{0.0.0.00000000}.", "");

获得id后,我们可以获得以下位置的注册表项: SOFTWARE \微软\的Windows \ CurrentVersion \ MMDevices \音频\渲染\ “CLASSID” \属性

RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine,RegistryView.Registry64);

Microsoft.Win32.RegistryKey key = localKey.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\MMDevices\\Audio\\Render\\" + classId + "\\Properties");

var searchKey = key.GetValue("{b3f8fa53-0004-438e-9003-51a46e139bfc},2").ToString().Split('.')[1];

获得searchKey后,您就可以获得Win32_PnPSignedDriver条目:

var mgmentsearcher = "SELECT * FROM Win32_PnPSignedDriver WHERE DeviceID like '%" + searchKey.Replace("\\", "\\\\") + "%'";            ManagementObjectCollection collection;

using (var searcher = new ManagementObjectSearcher(mgmentsearcher))
collection = searcher.Get();

foreach (var device in collection)
{
    var properties = device.Properties;

    var propertyEnumerator = properties.GetEnumerator();

    while (propertyEnumerator.MoveNext())
    {
        var p = (PropertyData)propertyEnumerator.Current;
        Console.WriteLine("Property {0}, Value: {1}", p.Name, p.Value);
    }
}

collection.Dispose();