Question

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);

}
Was it helpful?

Solution

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: output

Since the code is quite extensive I will not paste it here, instead, you can download it from this link: Source Code

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top