foreach (AudioSession session in AudioUtilities.GetAllSessions())
if (session.Process != null)
Console.WriteLine(session.Process.ProcessName);
public static class AudioUtilities
private static IAudioSessionManager2 GetAudioSessionManager()
IMMDevice speakers = GetSpeakers();
if (speakers.Activate(typeof(IAudioSessionManager2).GUID, CLSCTX.CLSCTX_ALL, IntPtr.Zero, out o) != 0 || o == null)
return o as IAudioSessionManager2;
public static AudioDevice GetSpeakersDevice()
return CreateDevice(GetSpeakers());
private static AudioDevice CreateDevice(IMMDevice dev)
Dictionary<string, object> properties = new Dictionary<string, object>();
dev.OpenPropertyStore(STGM.STGM_READ, out store);
store.GetCount(out propCount);
for (int j = 0; j < propCount; j++)
if (store.GetAt(j, out pk) == 0)
PROPVARIANT value = new PROPVARIANT();
int hr = store.GetValue(ref pk, ref value);
object v = value.GetValue();
if (value.vt != VARTYPE.VT_BLOB)
PropVariantClear(ref value);
string name = pk.ToString();
return new AudioDevice(id, (AudioDeviceState)state, properties);
public static IList<AudioDevice> GetAllDevices()
List<AudioDevice> list = new List<AudioDevice>();
IMMDeviceEnumerator deviceEnumerator = null;
deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator());
if (deviceEnumerator == null)
IMMDeviceCollection collection;
deviceEnumerator.EnumAudioEndpoints(EDataFlow.eAll, DEVICE_STATE.MASK_ALL, out collection);
collection.GetCount(out count);
for (int i = 0; i < count; i++)
collection.Item(i, out dev);
list.Add(CreateDevice(dev));
private static IMMDevice GetSpeakers()
IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator());
deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out speakers);
public static IList<AudioSession> GetAllSessions()
List<AudioSession> list = new List<AudioSession>();
IAudioSessionManager2 mgr = GetAudioSessionManager();
IAudioSessionEnumerator sessionEnumerator;
mgr.GetSessionEnumerator(out sessionEnumerator);
sessionEnumerator.GetCount(out count);
for (int i = 0; i < count; i++)
IAudioSessionControl ctl;
sessionEnumerator.GetSession(i, out ctl);
IAudioSessionControl2 ctl2 = ctl as IAudioSessionControl2;
list.Add(new AudioSession(ctl2));
Marshal.ReleaseComObject(sessionEnumerator);
Marshal.ReleaseComObject(mgr);
public static AudioSession GetProcessSession()
int id = Process.GetCurrentProcess().Id;
foreach (AudioSession session in GetAllSessions())
if (session.ProcessId == id)
private static extern int PropVariantClear(ref PROPVARIANT pvar);
[Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
private class MMDeviceEnumerator
CLSCTX_INPROC_SERVER = 0x1,
CLSCTX_INPROC_HANDLER = 0x2,
CLSCTX_LOCAL_SERVER = 0x4,
CLSCTX_REMOTE_SERVER = 0x10,
CLSCTX_ALL = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER
private enum DEVICE_STATE
[StructLayout(LayoutKind.Sequential)]
private struct PROPERTYKEY
public override string ToString()
return fmtid.ToString("B") + " " + pid;
private enum VARTYPE : short
[StructLayout(LayoutKind.Sequential)]
private struct PROPVARIANT
public ushort wReserved1;
public ushort wReserved2;
public ushort wReserved3;
public PROPVARIANTunion union;
return union.boolVal != 0;
return Marshal.PtrToStringUni(union.pwszVal);
return (Guid)Marshal.PtrToStructure(union.puuid, typeof(Guid));
return vt.ToString() + ":?";
[StructLayout(LayoutKind.Explicit)]
private struct PROPVARIANTunion
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMMDeviceEnumerator
int EnumAudioEndpoints(EDataFlow dataFlow, DEVICE_STATE dwStateMask, out IMMDeviceCollection ppDevices);
int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppEndpoint);
int GetDevice([MarshalAs(UnmanagedType.LPWStr)] string pwstrId, out IMMDevice ppDevice);
int RegisterEndpointNotificationCallback(IMMNotificationClient pClient);
int UnregisterEndpointNotificationCallback(IMMNotificationClient pClient);
[Guid("7991EEC9-7E89-4D85-8390-6C703CEC60C0"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMMNotificationClient
void OnDeviceStateChanged([MarshalAs(UnmanagedType.LPWStr)] string pwstrDeviceId, DEVICE_STATE dwNewState);
void OnDeviceAdded([MarshalAs(UnmanagedType.LPWStr)] string pwstrDeviceId);
void OnDeviceRemoved([MarshalAs(UnmanagedType.LPWStr)] string deviceId);
void OnDefaultDeviceChanged(EDataFlow flow, ERole role, string pwstrDefaultDeviceId);
void OnPropertyValueChanged([MarshalAs(UnmanagedType.LPWStr)] string pwstrDeviceId, PROPERTYKEY key);
[Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMMDeviceCollection
int GetCount(out int pcDevices);
int Item(int nDevice, out IMMDevice ppDevice);
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMMDevice
int Activate([MarshalAs(UnmanagedType.LPStruct)] Guid riid, CLSCTX dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
int OpenPropertyStore(STGM stgmAccess, out IPropertyStore ppProperties);
int GetId([MarshalAs(UnmanagedType.LPWStr)] out string ppstrId);
int GetState(out DEVICE_STATE pdwState);
[Guid("6f79d558-3e96-4549-a1d1-7d75d2288814"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IPropertyDescription
int GetPropertyKey(out PROPERTYKEY pkey);
int GetCanonicalName(out IntPtr ppszName);
int GetPropertyType(out short pvartype);
int GetDisplayName(out IntPtr ppszName);
[Guid("886d8eeb-8cf2-4446-8d02-cdba1dbdcf99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IPropertyStore
int GetCount(out int cProps);
int GetAt(int iProp, out PROPERTYKEY pkey);
int GetValue(ref PROPERTYKEY key, ref PROPVARIANT pv);
int SetValue(ref PROPERTYKEY key, ref PROPVARIANT propvar);
[Guid("BFA971F1-4D5E-40BB-935E-967039BFBEE4"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IAudioSessionManager
int GetAudioSessionControl([MarshalAs(UnmanagedType.LPStruct)] Guid AudioSessionGuid, int StreamFlags, out IAudioSessionControl SessionControl);
int GetSimpleAudioVolume([MarshalAs(UnmanagedType.LPStruct)] Guid AudioSessionGuid, int StreamFlags, ISimpleAudioVolume AudioVolume);
[Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IAudioSessionManager2
int GetAudioSessionControl([MarshalAs(UnmanagedType.LPStruct)] Guid AudioSessionGuid, int StreamFlags, out IAudioSessionControl SessionControl);
int GetSimpleAudioVolume([MarshalAs(UnmanagedType.LPStruct)] Guid AudioSessionGuid, int StreamFlags, ISimpleAudioVolume AudioVolume);
int GetSessionEnumerator(out IAudioSessionEnumerator SessionEnum);
int RegisterSessionNotification(IAudioSessionNotification SessionNotification);
int UnregisterSessionNotification(IAudioSessionNotification SessionNotification);
int RegisterDuckNotificationNotImpl();
int UnregisterDuckNotificationNotImpl();
[Guid("641DD20B-4D41-49CC-ABA3-174B9477BB08"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IAudioSessionNotification
void OnSessionCreated(IAudioSessionControl NewSession);
[Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IAudioSessionEnumerator
int GetCount(out int SessionCount);
int GetSession(int SessionCount, out IAudioSessionControl Session);
[Guid("bfb7ff88-7239-4fc9-8fa2-07c950be9c6d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAudioSessionControl2
int GetState(out AudioSessionState pRetVal);
int GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
int SetDisplayName([MarshalAs(UnmanagedType.LPWStr)]string Value, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
int GetIconPath([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
int SetIconPath([MarshalAs(UnmanagedType.LPWStr)] string Value, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
int GetGroupingParam(out Guid pRetVal);
int SetGroupingParam([MarshalAs(UnmanagedType.LPStruct)] Guid Override, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
int RegisterAudioSessionNotification(IAudioSessionEvents NewNotifications);
int UnregisterAudioSessionNotification(IAudioSessionEvents NewNotifications);
int GetSessionIdentifier([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
int GetSessionInstanceIdentifier([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
int GetProcessId(out int pRetVal);
int IsSystemSoundsSession();
int SetDuckingPreference(bool optOut);
[Guid("F4B1A599-7266-4319-A8CA-E70ACB11E8CD"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAudioSessionControl
int GetState(out AudioSessionState pRetVal);
int GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
int SetDisplayName([MarshalAs(UnmanagedType.LPWStr)]string Value, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
int GetIconPath([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);
int SetIconPath([MarshalAs(UnmanagedType.LPWStr)] string Value, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
int GetGroupingParam(out Guid pRetVal);
int SetGroupingParam([MarshalAs(UnmanagedType.LPStruct)] Guid Override, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
int RegisterAudioSessionNotification(IAudioSessionEvents NewNotifications);
int UnregisterAudioSessionNotification(IAudioSessionEvents NewNotifications);
[Guid("24918ACC-64B3-37C1-8CA9-74A66E9957A8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAudioSessionEvents
void OnDisplayNameChanged([MarshalAs(UnmanagedType.LPWStr)] string NewDisplayName, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
void OnIconPathChanged([MarshalAs(UnmanagedType.LPWStr)] string NewIconPath, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
void OnSimpleVolumeChanged(float NewVolume, bool NewMute, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
void OnChannelVolumeChanged(int ChannelCount, IntPtr NewChannelVolumeArray, int ChangedChannel, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
void OnGroupingParamChanged([MarshalAs(UnmanagedType.LPStruct)] Guid NewGroupingParam, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
void OnStateChanged(AudioSessionState NewState);
void OnSessionDisconnected(AudioSessionDisconnectReason DisconnectReason);
[Guid("87CE5498-68D6-44E5-9215-6DA47EF883D8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface ISimpleAudioVolume
int SetMasterVolume(float fLevel, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
int GetMasterVolume(out float pfLevel);
int SetMute(bool bMute, [MarshalAs(UnmanagedType.LPStruct)] Guid EventContext);
int GetMute(out bool pbMute);
public sealed class AudioSession : IDisposable
private AudioUtilities.IAudioSessionControl2 _ctl;
private Process _process;
internal AudioSession(AudioUtilities.IAudioSessionControl2 ctl)
if (_process == null && ProcessId != 0)
_process = Process.GetProcessById(ProcessId);
_ctl.GetProcessId(out i);
_ctl.GetSessionIdentifier(out s);
public string InstanceIdentifier
_ctl.GetSessionInstanceIdentifier(out s);
public AudioSessionState State
public Guid GroupingParam
_ctl.GetGroupingParam(out g);
_ctl.SetGroupingParam(value, Guid.Empty);
public string DisplayName
_ctl.GetDisplayName(out s);
_ctl.GetDisplayName(out s);
_ctl.SetDisplayName(value, Guid.Empty);
_ctl.SetIconPath(value, Guid.Empty);
private void CheckDisposed()
throw new ObjectDisposedException("Control");
public override string ToString()
if (!string.IsNullOrEmpty(s))
return "DisplayName: " + s;
return "Process: " + Process.ProcessName;
return "Pid: " + ProcessId;
Marshal.ReleaseComObject(_ctl);
public sealed class AudioDevice
internal AudioDevice(string id, AudioDeviceState state, IDictionary<string, object> properties)
public string Id { get; private set; }
public AudioDeviceState State { get; private set; }
public IDictionary<string, object> Properties { get; private set; }
public string Description
const string PKEY_Device_DeviceDesc = "{a45c254e-df1c-4efd-8020-67d146a850e0} 2";
Properties.TryGetValue(PKEY_Device_DeviceDesc, out value);
return string.Format("{0}", value);
public string ContainerId
const string PKEY_Devices_ContainerId = "{8c7ed206-3f8a-4827-b3ab-ae9e1faefc6c} 2";
Properties.TryGetValue(PKEY_Devices_ContainerId, out value);
return string.Format("{0}", value);
public string EnumeratorName
const string PKEY_Device_EnumeratorName = "{a45c254e-df1c-4efd-8020-67d146a850e0} 24";
Properties.TryGetValue(PKEY_Device_EnumeratorName, out value);
return string.Format("{0}", value);
public string InterfaceFriendlyName
const string DEVPKEY_DeviceInterface_FriendlyName = "{026e516e-b814-414b-83cd-856d6fef4822} 2";
Properties.TryGetValue(DEVPKEY_DeviceInterface_FriendlyName, out value);
return string.Format("{0}", value);
public string FriendlyName
const string DEVPKEY_Device_FriendlyName = "{a45c254e-df1c-4efd-8020-67d146a850e0} 14";
Properties.TryGetValue(DEVPKEY_Device_FriendlyName, out value);
return string.Format("{0}", value);
public override string ToString()
public enum AudioSessionState
public enum AudioDeviceState
public enum AudioSessionDisconnectReason
DisconnectReasonDeviceRemoval = 0,
DisconnectReasonServerShutdown = 1,
DisconnectReasonFormatChanged = 2,
DisconnectReasonSessionLogoff = 3,
DisconnectReasonSessionDisconnected = 4,
DisconnectReasonExclusiveModeOverride = 5