How can I change the Windows System Sound Volume using a C# Application?
-
Why did you remove the link for the duplicate? The Core Audio API's (Which control the mixer) don't just adjust single programs volumes, it is how you adjust the system volume too. Go actually read the answers in the duplicate and follow their links to the various MSDN articles.– Scott ChamberlainCommented Jul 13, 2014 at 16:02
-
But the answers in the duplicate do not provide the simplest solutions. Instead it suggests to use unneccessary libraries. Since my specific problem can easily be solved with built-in methods this is not a duplicate of the question linked as duplicate(Though it's pretty similar).– LostPhysxCommented Jul 25, 2015 at 10:14
7 Answers
I'm a bit late to the party but if you are looking now there's a nuget package available (AudioSwitcher.AudioApi.CoreAudio) that simplifies audio interactions. Install it then it’s as simple as:
CoreAudioDevice defaultPlaybackDevice = new CoreAudioController().DefaultPlaybackDevice;
Debug.WriteLine("Current Volume:" + defaultPlaybackDevice.Volume);
defaultPlaybackDevice.Volume = 80;
-
3The exact package is mentioned above (AudioSwitcher.AudioApi.CoreAudio). So, in the Package Manager Console its "Install-Package AudioSwitcher.AudioApi.CoreAudio". More details at nuget.org/packages/AudioSwitcher.AudioApi.CoreAudio– VmanCommented Jan 24, 2017 at 16:36
-
1For some reason, if I get a continuous loop of
A first chance exception of type 'System.NullReferenceException' occurred in AudioSwitcher.AudioApi.CoreAudio.dll
when I use this method. It's not stopping it from working but is there a way to eliminate this exception?– komodospCommented Apr 3, 2017 at 10:49 -
2
-
1this should be the accepted solution, not those "scripting the gui", autoit-like thing... Commented May 21, 2018 at 21:22
-
2AudioSwitcher.AudioApi.CoreAudio.dll is an abandoned buggy mess– WobblesCommented Sep 19, 2019 at 13:43
Here is the code:
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace Test
{
public class Test
{
private const int APPCOMMAND_VOLUME_MUTE = 0x80000;
private const int APPCOMMAND_VOLUME_UP = 0xA0000;
private const int APPCOMMAND_VOLUME_DOWN = 0x90000;
private const int WM_APPCOMMAND = 0x319;
[DllImport("user32.dll")]
public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg,
IntPtr wParam, IntPtr lParam);
private void Mute()
{
SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle,
(IntPtr)APPCOMMAND_VOLUME_MUTE);
}
private void VolDown()
{
SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle,
(IntPtr)APPCOMMAND_VOLUME_DOWN);
}
private void VolUp()
{
SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle,
(IntPtr)APPCOMMAND_VOLUME_UP);
}
}
}
Found on dotnetcurry
When using WPF you need to use new WindowInteropHelper(this).Handle
instead of this.Handle
(thanks Alex Beals)
-
I am trying to use this code in WPF app using C# , I am facing referencing problem at SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle, (IntPtr)APPCOMMAND_VOLUME_MUTE); --- This.handle is not available in WPF . can u check ?– ApoorvCommented Jan 18, 2016 at 11:59
-
Maybe you could try to use the answer below. It shouldn't interfere with the limitations of WPF. (Or work with WinForms. It may be older but still a lot better (imho)) Commented Jan 21, 2016 at 15:24
-
4Instead of
this.Handle
, usenew WindowInteropHelper(this).Handle
. Commented Jan 22, 2016 at 7:04 -
Why is it not working for me in my WinForms app? Do I missed anything? Commented Dec 17, 2016 at 0:30
-
1Our WinForms app runs on a PC with Windows Explorer not running. This doesn't work without Windows Explorer running. I don't yet know a workaround. Commented Nov 20, 2019 at 19:47
If the tutorials provided in the other answers are too involved you could try an implementation like this using the keybd_event function
[DllImport("user32.dll")]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
Usage:
keybd_event((byte)Keys.VolumeUp, 0, 0, 0); // increase volume
keybd_event((byte)Keys.VolumeDown, 0, 0, 0); // decrease volume
-
12
-
1It doesn't get much simpler than this, Might note that System.Windows.Forms is needed for the "keys" enum, but not required for the command. voldown = 174, volup = 175, volmute = 173 Commented Jan 5, 2016 at 0:19
-
@CasterTroy. This works great for simpler use cases without Windows Forms. And this approach provides zero dependency for any nuget packages. Spent hours for studying and trying other approaches and came back to this one. Kudos! And great thanks for this super smart solution!– TaglinerCommented Aug 22, 2019 at 13:40
-
And it appears it is compatible back to Windows 2000. I had to google for this version. It was post Win 98 version and one version before Win XP. Unlike alternative audio control implementations this is nice compatibility feature for home users who are still using Win XP.– TaglinerCommented Aug 22, 2019 at 15:41
In case you wish to set it to an exact value using the Core Audio APIs:
using CoreAudioApi;
public class SystemVolumeConfigurator
{
private readonly MMDeviceEnumerator _deviceEnumerator = new MMDeviceEnumerator();
private readonly MMDevice _playbackDevice;
public SystemVolumeConfigurator()
{
_playbackDevice = _deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);
}
public int GetVolume()
{
return (int)(_playbackDevice.AudioEndpointVolume.MasterVolumeLevelScalar * 100);
}
public void SetVolume(int volumeLevel)
{
if (volumeLevel < 0 || volumeLevel > 100)
throw new ArgumentException("Volume must be between 0 and 100!");
_playbackDevice.AudioEndpointVolume.MasterVolumeLevelScalar = volumeLevel / 100.0f;
}
}
-
whenimbored.xfx.net/2011/01/core-audio-for-net Here is a download for the api– DmanCommented Sep 19, 2016 at 9:02
-
2For anyone trying to find this API, they moved to GitHub github.com/filoe/cscore and as of this comment, reference
using CSCore.CoreAudioAPI;
Commented Oct 5, 2018 at 23:43 -
@SimpleSandman They've updated the API again.... I just looked at the associated tests for up to date examples: github.com/filoe/cscore/blob/master/CSCore.Test/CoreAudioAPI/… Commented Jun 21, 2019 at 17:32
-
Our WinForms app runs on a PC with Windows Explorer shut down. For us, both APPCOMMAND messages and keyboard emulation don't work. But this works! Commented Nov 20, 2019 at 19:58
-
C# code:
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume
{
int _0(); int _1(); int _2(); int _3();
int SetMasterVolumeLevelScalar(float fLevel, Guid pguidEventContext);
int _5();
int GetMasterVolumeLevelScalar(out float pfLevel);
int _7(); int _8(); int _9(); int _10(); int _11(); int _12();
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDevice
{
int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev);
}
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDeviceEnumerator
{
int _0();
int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint);
}
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] class MMDeviceEnumeratorComObject { }
public class Audio
{
private static readonly IAudioEndpointVolume _MMVolume;
static Audio()
{
var enumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator;
enumerator.GetDefaultAudioEndpoint(0, 1, out IMMDevice dev);
var aevGuid = typeof(IAudioEndpointVolume).GUID;
dev.Activate(ref aevGuid, 1, 0, out _MMVolume);
}
public static int Volume
{
get
{
_MMVolume.GetMasterVolumeLevelScalar(out float level);
return (int)(level * 100);
}
set
{
_MMVolume.SetMasterVolumeLevelScalar((float)value / 100, default);
}
}
}
Usage:
Audio.Volume = 50;
More info on MSDN.
You can add this library https://gist.github.com/sverrirs/d099b34b7f72bb4fb386 to your project and change the volume like this;
VideoPlayerController.AudioManager.SetMasterVolume(100);
The library also includes options for changing application volume, mute, getting current volume level etc. The namespace is called "Video Player Controller" but I used it in a Windows Forms App to change the system volume and it worked fine, so the "video" part is arbitrary.
-
I found this answer the most helpful because it sets the current device volume, not just the default device volume. This means you can switch playback devices and still have volume control without taking any additional steps. Certainly, setting the current device volume is also possible using CoreAudio directly, but you must take extra steps to find the current playback device. At the end of the day, this solution uses CoreAudio like the others, but wraps it in a pretty convenient package, all enclosed in a single file. Clear and concise.– Brian KCommented Jan 25, 2022 at 23:17
My code is a bit different but still using CoreAudio
downloaded the pkg : nuget install AudioSwitcher.AudioApi.CoreAudio -Version 3.0.0.1
using AudioSwitcher.AudioApi.CoreAudio;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
CoreAudioDevice defaultPlaybackDevice = new CoreAudioController().DefaultPlaybackDevice;
double vol = defaultPlaybackDevice.Volume;
defaultPlaybackDevice.Volume = defaultPlaybackDevice.Volume - 5.0;
defaultPlaybackDevice.Volume = defaultPlaybackDevice.Volume + 5.0;
}
}
-
2