Reputation: 1785
The goal was to mute a WebBrowser control that could have Flash video playing. So I found this code which is quite useful : https://stackoverflow.com/a/14322736/990618
Problem is some of the enumerations are nulls when you'd expect some kind of id from GetDisplayName
, I'd get 3-4 blanks and 2 that are ok like "Mozilla Firefox" and "@%SystemRoot%\System32\AudioSrv.Dll,-202"
which is system sounds.
So went ahead and tried GetProcessId, GetSessionIdentifier and GetSessionInstanceIdentifier.
GetProcessId
would return only zeros and ones, GetSessionIdentifier
same result as GetDisplayName
, GetSessionInstanceIdentifier
all blanks.
Why these blanks and zeros and ones?
Here's the modified EnumerateApplications
:
public static IEnumerable<string> EnumerateApplications()
{
// get the speakers (1st render + multimedia) device
IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator());
IMMDevice speakers;
deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out speakers);
// activate the session manager. we need the enumerator
Guid IID_IAudioSessionManager2 = typeof(IAudioSessionManager2).GUID;
object o;
speakers.Activate(ref IID_IAudioSessionManager2, 0, IntPtr.Zero, out o);
IAudioSessionManager2 mgr = (IAudioSessionManager2)o;
// enumerate sessions for on this device
IAudioSessionEnumerator sessionEnumerator;
mgr.GetSessionEnumerator(out sessionEnumerator);
int count;
sessionEnumerator.GetCount(out count);
for (int i = 0; i < count; i++)
{
IAudioSessionControl ctl;
IAudioSessionControl2 ctl2;
sessionEnumerator.GetSession(i, out ctl);
ctl2 = ctl as IAudioSessionControl2;
string dn;
UInt32 pid = 0;
string sout = "";
if (ctl2 != null)
ctl2.GetSessionIdentifier(out sout);
//ctl.GetDisplayName(out dn);
// ctl2.GetProcessId(out pid);
//yield return pid.ToString();
yield return sout;
if (ctl != null)
Marshal.ReleaseComObject(ctl);
if (ctl2 != null)
Marshal.ReleaseComObject(ctl2);
}
Marshal.ReleaseComObject(sessionEnumerator);
Marshal.ReleaseComObject(mgr);
Marshal.ReleaseComObject(speakers);
Marshal.ReleaseComObject(deviceEnumerator);
}
[Guid("bfb7ff88-7239-4fc9-8fa2-07c950be9c6d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAudioSessionControl2
{
[PreserveSig]
int GetProcessId([Out] [MarshalAs(UnmanagedType.U4)] out UInt32 processId);
[PreserveSig]
int GetSessionIdentifier([Out] [MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
[PreserveSig]
int GetSessionInstanceIdentifier([Out] [MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
}
Upvotes: 2
Views: 2419
Reputation: 1358
Having the correct declaration for the CoreAudio
interfaces makes all the difference...
I used your code, but used the interfaces declaration from the CoreAudioNET library and everything works as expected:
Since the code is quite extensive I will not paste it here, instead, you can download it from this link: Source Code
Upvotes: 3