我的系统插有两个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声音管理中做到了。
答案 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();