Reputation: 37633
I need some general method to change master audio volume from Windows XP to Windows 8 in C# because my application is going to work on those OS.
I have tried already http://www.geekpedia.com/tutorial176_Get-and-set-the-wave-sound-volume.html but it doesn't work under Windows 8. Perhaps it should work under Windows XP.
Anyway I need some compatible approach to do it. Any clue?
Upvotes: 0
Views: 14263
Reputation: 37633
So my solutions is to combine 2 projects:
http://www.geekpedia.com/tutorial176_Get-and-set-the-wave-sound-volume.html
The final code should be like (It uses NAudio framework)
static class NativeMethods
{
[DllImport("winmm.dll", EntryPoint = "waveOutSetVolume")]
public static extern int WaveOutSetVolume(IntPtr hwo, uint dwVolume);
[DllImport("winmm.dll", SetLastError = true)]
public static extern bool PlaySound(string pszSound, IntPtr hmod, uint fdwSound);
}
public static class MSWindowsFriendlyNames
{
public static string WindowsXP { get { return "Windows XP"; } }
public static string WindowsVista { get { return "Windows Vista"; } }
public static string Windows7 { get { return "Windows 7"; } }
public static string Windows8 { get { return "Windows 8"; } }
}
public static class SistemVolumChanger
{
public static void SetVolume(int value)
{
if (value < 0)
value = 0;
if (value > 100)
value = 100;
var osFriendlyName = GetOSFriendlyName();
if (osFriendlyName.Contains(MSWindowsFriendlyNames.WindowsXP))
{
SetVolumeForWIndowsXP(value);
}
else if (osFriendlyName.Contains(MSWindowsFriendlyNames.WindowsVista) || osFriendlyName.Contains(MSWindowsFriendlyNames.Windows7) || osFriendlyName.Contains(MSWindowsFriendlyNames.Windows8))
{
SetVolumeForWIndowsVista78(value);
}
else
{
SetVolumeForWIndowsVista78(value);
}
}
public static int GetVolume()
{
int result = 100;
try
{
MMDeviceEnumerator DevEnum = new MMDeviceEnumerator();
MMDevice device = DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);
result = (int)(device.AudioEndpointVolume.MasterVolumeLevelScalar * 100);
}
catch (Exception)
{
}
return result;
}
private static void SetVolumeForWIndowsVista78(int value)
{
try
{
MMDeviceEnumerator DevEnum = new MMDeviceEnumerator();
MMDevice device = DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);
device.AudioEndpointVolume.MasterVolumeLevelScalar = (float)value / 100.0f;
}
catch (Exception)
{
}
}
private static void SetVolumeForWIndowsXP(int value)
{
try
{
// Calculate the volume that's being set
double newVolume = ushort.MaxValue * value / 10.0;
uint v = ((uint)newVolume) & 0xffff;
uint vAll = v | (v << 16);
// Set the volume
int retVal = NativeMethods.WaveOutSetVolume(IntPtr.Zero, vAll);
}
catch (Exception)
{
}
}
private static string GetOSFriendlyName()
{
string result = string.Empty;
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem");
foreach (ManagementObject os in searcher.Get())
{
result = os["Caption"].ToString();
break;
}
return result;
}
}
Update #1. Year 2015 Basically it uses NAudio framework. So nowdays some methods and properties of NAudio have other names.
For instance
eDataFlow.eRender is now DataFlow.Render
and
eRole.eMultimedia is Role.Multimedia
Upvotes: 5
Reputation: 1444
For windows 7+:
There are some problems with the accepted answer. Because the codeproject page is deleted it now has no context.
You need to get NAudio from Nuget
Replace the first with the second
MMDevice device = DevEnum.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia);
MMDevice device = DevEnum.GetDefaultAudioEndpoint((DataFlow)0, (Role)1);
Just a quick heads-up if you are lost trying to fix the errors with the accepted-answer code.
Upvotes: 1