1

Story first: ( Skip if not interested )

I've encountered a very annoying daily task where every time I play a game, I need to switch between my speakers and my headphones. This involves in getting to the Control Panel ( Because for some reason Windows 10 removed the option to right click the audio icon in the taskbar and get to the "Manage audio devices" quick ), going to Hardware and Sound, then Manage audio devices, then need to disable the speaker, enable the headphones, and vice versa.

ANNOYING task that I could ( hopefully with your help ) automate with just a program running in background and listening for a "Hotkey". ( There is probably an existing program already for that task, but I wish to learn WinApi through a problem I encountered, to motivate myself )


Now, I started to learn WinApi for that matter, and got stuck in how can I implement such a task, where I can disable one audio device and enable another one. My logic says that those devices have some sort of ID, and I can manipulate various properties through this ID.

I used the example from MSDN to enumerate every audio device using EnumAudioEndpoints And tried to get the device's properties so I could change them later. I Hoped I will encounter some sort of "state" variable which I can change later with IPropertyStore::SetValue function.

In the example, they used this piece of code:

hr = pProps->GetValue(PKEY_Device_FriendlyName, &varName);

Where PKEY_Device_FriendlyName key comes from functiondiscoverykeys_devpkey header. This is documented very badly ( if not at all ), I tried every single PROPERTYKEY ( Especially PKEY_Device_DevNodeStatus ), but each one returned empty results (Meaning there is no such property I can change to disable or enable a device through those interfaces they used), Excluding 3 properties :

  • PKEY_DeviceInterface_FriendlyName
  • PKEY_Device_DeviceDesc
  • PKEY_Device_FriendlyName

I've played with this a long time now. Asking for your help, how can I achieve the results I want ?

Wahalez
  • 489
  • 1
  • 6
  • 22

1 Answers1

1

There may be no programming method to achieve this requirement.

As @Larry Osterman said that,

There is no public API which allows you to change the default audio device, that is functionality that is considered to be under the users control. This has always been the case in Windows.

Having said that, if you search the web, there are a number of people who have reverse engineered the APIs that are used in Windows Vista to do this, but I'm not going to point you to them (the reverse engineered APIs are internal unsupported APIs and may change without notice from Microsoft). You use these solutions at your own peril.

Strive Sun
  • 5,988
  • 1
  • 9
  • 26
  • Probably this is why I couldn't find an appropriate answer on the internet. What if we hack a bit ? I mean that maybe we could change the registry of an MMDevice state from disabled to enabled and vice versa. + I found 2 programs that are open source. One is the microsoft's [devcon](https://github.com/Microsoft/Windows-driver-samples/tree/master/setup/devcon), and the other one is [Audio Switcher](https://audioswit.ch/er). Somehow they achieved this, but I cannot find in the source code how, I'm getting lost in c#. Could you help me out ? – Wahalez Sep 11 '20 at 06:28
  • @Wahalez I don’t recommend that you directly modify the registry keys. One wrong edit, in the wrong entry, can render a Windows machine unusable or worse -- unbootable. `devcon.exe` allows to disable/enable devices in Device Manager - this is something different than disable/enable in sound properties. To be precise, this is not what you want. For Audio Switcher, I recommend you to ask the software developer. – Strive Sun Sep 14 '20 at 09:57
  • I dug into it and found a workaround with default audio device flag. Make the two (or more) devices all enabled and just switch the default flag between them. Otherwise I didn't find any way in WinAPI to programmatically enable an audio device, they only give you an option to switch the default flag to different device. – Wahalez Jul 26 '21 at 13:31