Set Windows volume with C #

I searched the Internet for a way to control the sound of my computer with C #. I found this code that works fine.

public static float GetMasterVolume() { // get the speakers (1st render + multimedia) device IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator()); IMMDevice speakers; const int eRender = 0; const int eMultimedia = 1; deviceEnumerator.GetDefaultAudioEndpoint(eRender, eMultimedia, out speakers); object o; speakers.Activate(typeof(IAudioEndpointVolume).GUID, 0, IntPtr.Zero, out o); IAudioEndpointVolume aepv = (IAudioEndpointVolume)o; float volume = aepv.GetMasterVolumeLevelScalar(); Marshal.ReleaseComObject(aepv); Marshal.ReleaseComObject(speakers); Marshal.ReleaseComObject(deviceEnumerator); return volume; } [ComImport] [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] private class MMDeviceEnumerator { } [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IAudioEndpointVolume { void _VtblGap1_6(); float GetMasterVolumeLevelScalar(); } [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IMMDeviceEnumerator { void _VtblGap1_1(); [PreserveSig] int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice ppDevice); } [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] private interface IMMDevice { [PreserveSig] int Activate([MarshalAs(UnmanagedType.LPStruct)] Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface); } 

This is the getVolume function. I think there should be a similar way to set the volume. I came across this method:

SetMasterVolumeLevelScalar ()

 HRESULT SetMasterVolumeLevelScalar( [in] float fLevel, [in] LPCGUID pguidEventContext ); 

But I can not understand the second parameter. Any help would be appreciated.

+5
source share
2 answers

I see that you have already solved the problem, but you wanted to give an official answer to someone who is curious or in need of help.

When you call SetMasterVolumeLevelScalar , you pass the volume as a percentage from 0.0 to 1.0, and you pass the GUID. You can also go to Null; But. The reason for switching to the GUID is that any other application changes can check the changes and see if they were or another application. For instance:

If you register with OnNotify to change the volume, you will get a structure every time you change the volume. The first field in the structure is the GUID. If you use a persistent GUID to change the volume, then this structure will show you that you are your own GUID; you can compare it and ignore it or something else. If the structure goes to NULL or another GUID, then you know that another application has changed the volume, and perhaps you want to do something different at this point.

Hope this helps :)

+1
source

Define your interface ...

 [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IAudioEndpointVolume { // ... Int32 GetMasterVolumeLevelScalar(ref Single pfLevel); Int32 SetMasterVolumeLevelScalar(Single fLevel, Guid pguidEventContext); // ... } 

Then in your class, for example:

 public class EndpointVolume { private readonly Guid m_GuidEventContext; private IAudioEndpointVolume m_AudioEndpoint; public EndpointVolume() { m_GuidEventContext = Guid.NewGuid(); m_AudioEndpoint = ... } public Single MasterVolume { get { Single level = 0.0f; Int32 res = m_AudioEndpoint.GetMasterVolumeLevelScalar(ref level); if (retVal != 0) throw new Exception("AudioEndpointVolume.GetMasterVolumeLevelScalar()"); return level; } set { Single level = value; if (level < 0.0f) level = 0.0f; else if (level > 1.0f) level = 0.0f; Int32 res = m_AudioEndpoint.SetMasterVolumeLevelScalar(level, m_GuidEventContext); if (res!= 0) throw new Exception("AudioEndpointVolume.SetMasterVolumeLevelScalar()"); } } // ... } 

The pguidEventContext parameter pguidEventContext used to determine the context of the current event, so changes made to the main volume are reflected on all other clients. From the official documentation :

Context value for the IAudioEndpointVolumeCallback :: OnNotify method. This parameter indicates the context event GUID. If the SetMasterVolumeLevelScalar call changes the volume level of the endpoint, all clients that register IAudioEndpointVolumeCallback interfaces with this endpoint will receive notifications. When implementing the OnNotify method, the client can check the GUID of the context event to see if the other client is the source of the volume change event. If the caller supplies a NULL pointer for this parameter, the notification procedure receives the context GUID value GUID_NULL.

0
source

Source: https://habr.com/ru/post/1247137/


All Articles