/// <summary> /// Finds the matching process and volume control /// </summary> /// <param name="processName">The name of the process to find</param> /// <param name="selectedProcess">The selected process</param> /// <param name="volumeControl">The volume control object</param> private static void FindMatchingProcess(string processName, out Process selectedProcess, out ISimpleAudioVolume volumeControl) { selectedProcess = null; volumeControl = null; // First find the list of matching processes Process[] matchingProcesses = Process.GetProcessesByName(processName); if (matchingProcesses != null && matchingProcesses.Length > 0) { // Attempt to see if we can find an audio session with the same Process ID as one we have found IMMDeviceEnumerator deviceEnumerator = null; IMMDevice device = null; IAudioSessionManager2 sessionManager = null; IAudioSessionEnumerator sessionEnumerator = null; object activatedObject = null; Guid sessionManagerGuid = typeof(IAudioSessionManager2).GUID; try { // Create the Device Enumerator deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator()); // Get the default audio device if (deviceEnumerator != null) { deviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia, out device); } // Get the Session Manager if (device != null) { device.Activate(ref sessionManagerGuid, (uint)0, IntPtr.Zero, out activatedObject); sessionManager = activatedObject as IAudioSessionManager2; activatedObject = null; } // Get the Session Enumerator if (sessionManager != null) { sessionManager.GetSessionEnumerator(out sessionEnumerator); } // Look through the list of Sessions and find one with a matching process ID. if (sessionEnumerator != null) { int totalSessions = 0; sessionEnumerator.GetCount(out totalSessions); for (int currentSession = 0; currentSession < totalSessions; currentSession++) { IAudioSessionControl currentSessionControl = null; sessionEnumerator.GetSession(currentSession, out currentSessionControl); IAudioSessionControl2 currentSessionControl2 = currentSessionControl as IAudioSessionControl2; if (currentSessionControl2 != null) { uint processID = 0; currentSessionControl2.GetProcessID(out processID); foreach (Process currentProcess in matchingProcesses) { // We found the correct process and audio session if (currentProcess.Id == processID) { selectedProcess = currentProcess; volumeControl = currentSessionControl as ISimpleAudioVolume; break; } } } if (selectedProcess != null) { // We found the volume control break; } else { // Free the current session Marshal.ReleaseComObject(currentSessionControl); } } } } finally { // Clean up the COM Objects that we used if (activatedObject != null) { Marshal.ReleaseComObject(activatedObject); } if (sessionEnumerator != null) { Marshal.ReleaseComObject(sessionEnumerator); } if (sessionManager != null) { Marshal.ReleaseComObject(sessionManager); } if (device != null) { Marshal.ReleaseComObject(device); } if (deviceEnumerator != null) { Marshal.ReleaseComObject(deviceEnumerator); } } // If we get here for some reason and don't have a matching process then we will just take the first one with a valid Window Handle if (selectedProcess == null) { foreach (Process currentProcess in matchingProcesses) { if (currentProcess != null && currentProcess.MainWindowHandle != IntPtr.Zero) { selectedProcess = currentProcess; break; } } } } }