It took me quite some digging to find a clean way to set the standard default volume without external libs. So here the result.
If you do not want the console output, remove the writeline, and change the project from Console to Windows App.
I suggest using it as a Scheduled Task triggered by connect to user session and/or similar.
It is composed of a couple of bits and pieces combined/reduced primarily from these three.
https://stackoverflow.com/questions/31928429
https://stackoverflow.com/questions/36625576
https://social.msdn.microsoft.com/Forums/expression/en-US/90c6405d-44f6-48ce-82aa-c48a9b09dfb4
using System;
using System.Runtime.InteropServices;
namespace SetAudioLevel {
class Program {
[ComImport]
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMMDeviceEnumerator {
void _VtblGap1_1();
int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice ppDevice);
}
private static class MMDeviceEnumeratorFactory {
public static IMMDeviceEnumerator CreateInstance() {
return (IMMDeviceEnumerator)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E"))); // a MMDeviceEnumerator
}
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IMMDevice {
int Activate([MarshalAs(UnmanagedType.LPStruct)] Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
}
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioEndpointVolume
{
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE RegisterControlChangeNotify(/* [in] */__in IAudioEndpointVolumeCallback *pNotify) = 0;
int RegisterControlChangeNotify(IntPtr pNotify);
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE UnregisterControlChangeNotify(/* [in] */ __in IAudioEndpointVolumeCallback *pNotify) = 0;
int UnregisterControlChangeNotify(IntPtr pNotify);
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetChannelCount(/* [out] */ __out UINT *pnChannelCount) = 0;
int GetChannelCount(ref uint pnChannelCount);
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMasterVolumeLevel( /* [in] */ __in float fLevelDB,/* [unique][in] */ LPCGUID pguidEventContext) = 0;
int SetMasterVolumeLevel(float fLevelDB, Guid pguidEventContext);
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetMasterVolumeLevelScalar( /* [in] */ __in float fLevel,/* [unique][in] */ LPCGUID pguidEventContext) = 0;
int SetMasterVolumeLevelScalar(float fLevel, Guid pguidEventContext);
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMasterVolumeLevel(/* [out] */ __out float *pfLevelDB) = 0;
int GetMasterVolumeLevel(ref float pfLevelDB);
//virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetMasterVolumeLevelScalar( /* [out] */ __out float *pfLevel) = 0;
int GetMasterVolumeLevelScalar(ref float pfLevel);
}
static void Main(string[] args) {
int Level = 20;
if (args.Length == 1) { int.TryParse(args[0], out Level); }
try {
IMMDeviceEnumerator deviceEnumerator = MMDeviceEnumeratorFactory.CreateInstance();
IMMDevice speakers;
const int eRender = 0;
const int eMultimedia = 1;
deviceEnumerator.GetDefaultAudioEndpoint(eRender, eMultimedia, out speakers);
object aepv_obj;
speakers.Activate(typeof(IAudioEndpointVolume).GUID, 0, IntPtr.Zero, out aepv_obj);
IAudioEndpointVolume aepv = (IAudioEndpointVolume)aepv_obj;
Guid ZeroGuid = new Guid();
int res = aepv.SetMasterVolumeLevelScalar(Level / 100f, ZeroGuid);
Console.WriteLine($"Audio set for {Level}%");
//Console.Beep();
} catch (Exception ex) { Console.WriteLine($"**Could not set audio level** {ex.Message}"); }
}
}
}
.