I have a system that has two PnP Speakers plugged in. They are both the same type of device. One will be installed in the front and one will be installed in the rear. It is possible to have the manufacturer add some driver level id so we can know which is where. I need to be able to determine which device I am looking at from getting the device information when I setting up the audio outputs of a play.
When I get the device information from the 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);
Gives me an output like:
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
I have the following properties: DeviceId DisplayName OutputFormat Role
For both devices everything is the same except for the Display Name which will have a numeric number associated with that instance. We will be installing many of these devices so I can't guarantee those numbers will be consistent.
I am trying to correlate this device instance with some driver level value that will allow me to know what physical device is plugged in.
I was then going to use some WMI query on the Win32_SoundDevice or something like that but I can't find any common link to get from the XAudio2 Device Details to the Wmi Sound Device Instance.
Any help would be appreciated. I know it can be done because I see they do it in Windows sound management.
The answer is you need to map the device id to the Registry and then map the registry entry to Win32_PnPSignedDriver entries:
1st get the Device Id from the Device Details:
var device = _xAudio2Instances[TchDevice.Core].GetDeviceDetails(i);
classId = device.DeviceId.Replace("{0.0.0.00000000}.", "");
Once you have the id we can get the registry entry for this located at: SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\"classId"\Properties
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];
Once you get the searchKey you can then get the Win32_PnPSignedDriver entries:
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();