By user1974519


2013-01-13 17:20:05 8 Comments

I want to control other application volume(firefox).

i can do it with Volume Mixer

enter image description here

What is the libraries of the Volume Mixer?

1 comments

@Simon Mourier 2013-01-14 16:43:13

Here is a sample C# Console Application that does it. It's based on the Windows Core Audio Library. It works only on Windows 7 and higher.

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;

namespace SetAppVolumne
{
    class Program
    {
        static void Main(string[] args)
        {
            const string app = "Mozilla Firefox";

            foreach (string name in EnumerateApplications())
            {
                Console.WriteLine("name:" + name);
                if (name == app)
                {
                    // display mute state & volume level (% of master)
                    Console.WriteLine("Mute:" + GetApplicationMute(app));
                    Console.WriteLine("Volume:" + GetApplicationVolume(app));

                    // mute the application
                    SetApplicationMute(app, true);

                    // set the volume to half of master volume (50%)
                    SetApplicationVolume(app, 50);
                }
            }
        }

        public static float? GetApplicationVolume(string name)
        {
            ISimpleAudioVolume volume = GetVolumeObject(name);
            if (volume == null)
                return null;

            float level;
            volume.GetMasterVolume(out level);
            return level * 100;
        }

        public static bool? GetApplicationMute(string name)
        {
            ISimpleAudioVolume volume = GetVolumeObject(name);
            if (volume == null)
                return null;

            bool mute;
            volume.GetMute(out mute);
            return mute;
        }

        public static void SetApplicationVolume(string name, float level)
        {
            ISimpleAudioVolume volume = GetVolumeObject(name);
            if (volume == null)
                return;

            Guid guid = Guid.Empty;
            volume.SetMasterVolume(level / 100, ref guid);
        }

        public static void SetApplicationMute(string name, bool mute)
        {
            ISimpleAudioVolume volume = GetVolumeObject(name);
            if (volume == null)
                return;

            Guid guid = Guid.Empty;
            volume.SetMute(mute, ref guid);
        }

        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;
                sessionEnumerator.GetSession(i, out ctl);
                string dn;
                ctl.GetDisplayName(out dn);
                yield return dn;
                Marshal.ReleaseComObject(ctl);
            }
            Marshal.ReleaseComObject(sessionEnumerator);
            Marshal.ReleaseComObject(mgr);
            Marshal.ReleaseComObject(speakers);
            Marshal.ReleaseComObject(deviceEnumerator);
        }

        private static ISimpleAudioVolume GetVolumeObject(string name)
        {
            // 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);

            // search for an audio session with the required name
            // NOTE: we could also use the process id instead of the app name (with IAudioSessionControl2)
            ISimpleAudioVolume volumeControl = null;
            for (int i = 0; i < count; i++)
            {
                IAudioSessionControl ctl;
                sessionEnumerator.GetSession(i, out ctl);
                string dn;
                ctl.GetDisplayName(out dn);
                if (string.Compare(name, dn, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    volumeControl = ctl as ISimpleAudioVolume;
                    break;
                }
                Marshal.ReleaseComObject(ctl);
            }
            Marshal.ReleaseComObject(sessionEnumerator);
            Marshal.ReleaseComObject(mgr);
            Marshal.ReleaseComObject(speakers);
            Marshal.ReleaseComObject(deviceEnumerator);
            return volumeControl;
        }
    }

    [ComImport]
    [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
    internal class MMDeviceEnumerator
    {
    }

    internal enum EDataFlow
    {
        eRender,
        eCapture,
        eAll,
        EDataFlow_enum_count
    }

    internal enum ERole
    {
        eConsole,
        eMultimedia,
        eCommunications,
        ERole_enum_count
    }

    [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IMMDeviceEnumerator
    {
        int NotImpl1();

        [PreserveSig]
        int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice);

        // the rest is not implemented
    }

    [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IMMDevice
    {
        [PreserveSig]
        int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);

        // the rest is not implemented
    }

    [Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IAudioSessionManager2
    {
        int NotImpl1();
        int NotImpl2();

        [PreserveSig]
        int GetSessionEnumerator(out IAudioSessionEnumerator SessionEnum);

        // the rest is not implemented
    }

    [Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IAudioSessionEnumerator
    {
        [PreserveSig]
        int GetCount(out int SessionCount);

        [PreserveSig]
        int GetSession(int SessionCount, out IAudioSessionControl Session);
    }

    [Guid("F4B1A599-7266-4319-A8CA-E70ACB11E8CD"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IAudioSessionControl
    {
        int NotImpl1();

        [PreserveSig]
        int GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] out string pRetVal);

        // the rest is not implemented
    }

    [Guid("87CE5498-68D6-44E5-9215-6DA47EF883D8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface ISimpleAudioVolume
    {
        [PreserveSig]
        int SetMasterVolume(float fLevel, ref Guid EventContext);

        [PreserveSig]
        int GetMasterVolume(out float pfLevel);

        [PreserveSig]
        int SetMute(bool bMute, ref Guid EventContext);

        [PreserveSig]
        int GetMute(out bool pbMute);
    }
}

Note: I have not defined the interfaces completely, only what was needed for the code to work.

@joostmakaay 2013-12-19 12:10:29

How can i change this code, so it changes the volume of Spotify?

@Simon Mourier 2013-12-19 13:16:39

Maybe you can try with "Spotify" instead of "Mozilla Firefox"

@joostmakaay 2013-12-19 13:19:28

Already tried, but the Volume mixer doesn't give back a DisplayName for Spotify, it only does for Firefox and some kind of .dll

@Simon Mourier 2013-12-19 17:26:56

On Windows 7, there is an IAudioSessionControl2 interface that can get you the process id. From there you can determine if it's spotify or not. If you don't know how to do it, ask another question.

@Bliss 2014-01-05 15:50:03

Simon, your simple & neat solution could be very useful for me as well, if audio-playing processes could have been enumerated by process-ID, rather than by Display-Name. Could you please post a modified version of the above, utilizing the IAudioSessionControl2 interface, to accomplish that, as you suggested. I tried, but... couldn't.

@Simon Mourier 2014-01-05 19:23:46

@bliss - this is another problem, so, like I said, you should ask another question

@Bliss 2014-01-05 20:45:44

Hello Simon. I've started another question. This link shall bring you to it. Thank you.

@csharp newbie 2014-02-26 19:57:31

@Simon Mourier - i got this error in EnumerateApplications() function - here is screenshot: i.imgur.com/YzbgOKH.png Can you please help?

@Simon Mourier 2014-02-27 09:22:31

@jstq - that's another problem. please create a new question.

@qakmak 2015-04-01 06:14:54

@SimonMourier, But use this way how to set the system global volume?

@ElektroStudios 2018-08-24 02:48:13

While I appreciate the helpful answer that give us a hint, I also think doing a solution based on the window title is pure useless (what happens for processes that has an empty window title?, the solution returns empty strings because that), and the author has ignored the multiple requests to rework the solution to use a process id, because as it is is a very bad design and bad feedback/support that does not deserve to upvote his comments like some people did, sorry.

@ElektroStudios 2018-08-24 02:53:14

Anyway, adapting the code to find the process by a pid is easy, the steps: 1. implement the IAudioSessionControl2 interface which you can find here: github.com/xenolightning/AudioSwitcher/blob/… 2. in the EnumerateApplications function just convert the ctl object from IAudioSessionControl to IAudioSessionControl2, and finally do minor adaptions to call the ctl.GetProcessId function from that, and same in GetApplicationVolume, SetApplicationVolume, etc.

@Simon Mourier 2018-08-24 06:29:33

@ElektroStudios - The display name is not the same as the window title and the solution by process id is available here since 2014: stackoverflow.com/questions/20938934/… but note it requires Windows 7.

@ElektroStudios 2018-08-24 21:06:41

@Simon Mourier Nice to know you finally did it process id based, thanks for commenting it.

Related Questions

Sponsored Content

20 Answered Questions

[SOLVED] Reading settings from app.config or web.config in .net

26 Answered Questions

[SOLVED] Why not inherit from List<T>?

20 Answered Questions

25 Answered Questions

[SOLVED] ASP.NET Web Site or ASP.NET Web Application?

34 Answered Questions

[SOLVED] How do I make a textbox that only accepts numbers?

1 Answered Questions

[SOLVED] Reading the value of the volume in the windows mixer

1 Answered Questions

[SOLVED] OPEN the volume mixer in Visual Basic

  • 2016-01-16 20:17:13
  • Klink45
  • 239 View
  • 0 Score
  • 1 Answer
  • Tags:   vb.net

1 Answered Questions

[SOLVED] How can i control the volume of a specific software in the windows Volume Mixer?

  • 2015-11-16 00:34:12
  • Sharondohp Sharonas
  • 259 View
  • 0 Score
  • 1 Answer
  • Tags:   c# .net winforms

20 Answered Questions

[SOLVED] Best way to parse command line arguments in C#?

Sponsored Content