Mute Sound Volume in WSH

November 7th, 2008

I’ve seen this question several times over the past few weeks so I decided to sit down and find a solution. There’s a plethora of reasons why you might want to mute or unmute sound volume from within a WSH script. Until now, there’s been no viable solution.

There are several third-party ActiveX controls available that offer the ability to mute sound volume; but if you’re like me, you’d much rather have a native way of doing this. Third-party ActiveX controls hinder script compatibility (and portability) because they are required to be installed on every system.

Knowing that neither WScript nor VBScript had a method of doing this, my first instinct was to look at WMI. That was a no-go. WMI allows you to work with sound hardware, but it doesn’t allow you to control it’s functionality.

Next, I looked to the command-line. I knew that Sndvol32.exe controlled was the Sound and Volume control, but it doesn’t provide any useful command-lines.

Finally, I decided to look toward some native objects. In many cases scriptable objects like Word and Media Player can offer methods of interacting with the Windows API that are otherwise inaccessible to scripters. Again, no such luck.

I had exhausted all of my normal avenues of approach, and, to be honest, was quite ready to beat my head off the wall. I was just about to give in and choose a third-party ActiveX or command-line utility when I remembered something: the multimedia keyboard!

Windows has native support for multimedia keyboards and these keyboards offer a nifty little Mute button. In short, this means that Windows can detect (and respond) to that particular key code. My problem then became: How on earth do I simulate that keystroke?

Anytime you’re working with keystrokes you should be thinking of the WshShell object’s SendKeys method. However, we’ve been told that it only accepts predefined string values–namely, common alphanumeric characters and some predefined symbolic names. This got me to thinking. How does this function really work.

The SendKeys method accepts can accept a string characters. This would indicate that it iterates through each of those characters. Logically, that would indicate that it’s functionality is based on character codes, rather than the specific characters themselves. So I decided to try it. A little research revealed that the character code for the Mute button was 0xAD (or decimal 173).

Set WshShell = CreateObject("WScript.Shell")
WshShell.SendKeys(chr(&hAD))

You may recall that VBScript provides the Chr() function that returns a string representation for a character based on its hex or decimal value. This is commonly used to return non-printable characters, which conveniently enough is exactly what we need here. You can see above that I’m simply passing the result of the Chr() function directly to the SendKeys method.

Voila! It works. This code will toggle the sound volume on and off.

[donotprint] [/donotprint] Please use the trackback link when linking to this post.

Related Posts:

Add to Technorati Favorites

15 Responses to “Mute Sound Volume in WSH”

  1. Rob Bos Says:

    Clever solution, but how can you detect whether the system is muted or not? Being able to toggle in a script isn’t much use if you don’t know the mute state.

    I want to ensure that a laptop is muted. Toggling doesn’t do me much good if it’s already muted. :)

  2. Nilpo Says:

    Hi Rob.

    I haven’t found any reliable way of determining whether the system sound is currently muted or not. However, I have a couple of other solutions that may work for you. Are you looking to mute the sound all of the time or just during certain events? Some options might include:

    1. enabling/disabling the sound device,
    2. enabling/disabling system sounds,
    3. or starting/stopping the Windows Audio service.

  3. Rob Bos Says:

    I’d like people to have the option of turning on the sound at any time. I work at a university library, and I’m specifically talking about lending laptops. Headphones ought to be usable. Thus all sound should be off unless the user specifically enables it.

    So I’d hoped to be able to mute the system sound on logout and startup.

    It’s possible that disabling the various beeps and blorts that Windows throws out might be sufficient, but it seems inelegant. :)

  4. Daniel Skantze Says:

    Nice one!

  5. Daniel Skantze Says:

    Another solution is to just lower the volume:
    WshShell.SendKeys(chr(174))

    Or raise the volume:
    WshShell.SendKeys(chr(175))

    Each 174 or 175 code changes the volume only by a small amount so you will have to repeat the command.

  6. Alexander Says:

    I use it for map the STOP key (browser) of a keyboard that hasn’t MUTE key.
    All this throught “Tweak UI” utility on Windows XP.

    Thanks !!!

  7. Arkady Says:

    So, that does indeed mean that one can check for system state with conditional and then act on it - “if WshShell.SendKeys(chr(?)) is greater then 173 then WshShell.SendKeys(chr(173))”

    What would be the syntax to do it? Please help.

  8. Nilpo Says:

    Unfortunately, you cannot use this method of checking the current system volume. The SendKeys method only simulates key strokes. It does not offer a return value as it is not a function.

  9. Robin Says:

    That’s really sweet! I’d often wondered how those keyboards worked.

  10. Dave Says:

    Thanks

  11. hpo14 Says:

    i dont know why this doesnt work on my windows XP ?

  12. Cozman Says:

    Works fine on xp sp3. Thanks a bunch.
    I wish I could find the cause of it auto-muting.
    It mutes itself many times a day.

  13. Rjnn Suibne Says:

    If you do something like this:

    Set WshShell = CreateObject(”WScript.Shell”)
    WshShell.SendKeys “{” & chr(174) & ” 25}”

    which sets the volume to 0. Unorthodox, but it works. Not sure if it is a true mute as I have heard minute sound at volume 0 on some machines but is a trick I use.

    Usually I use that on a Computer at home I have hooked up to a TV. I need to play movies at a higher volume, but I keep my video game volume low, so after the WshShell.SendKeys “{” & chr(174) & ” 25}” line, I wrote something like:

    WshShell.SendKeys “{” & chr(175) & chr(32) & volUp”}”

    where volUp is a specified value in range of 0-25.

  14. WildCard Says:

    One way you can make good use of the keyboard press mute toggle is to unmute the system volume first. Raising or lowering the system volume will automatically unmute.

    By raising the volume one notch and bringing it back one notch (returning it to what ever level it was set to) and then using the mute toggle to ensures the system volume will be muted each and every time the script is run.

    ‘Mute system volume script (keyboard press volume control)
    Set WshShell = CreateObject(”WScript.Shell”)

    ‘Raise Volume 1 step (keyboard press volume up)
    ‘Lower Volume 1 step (keyboard press volume down)
    WshShell.SendKeys (chr(175))
    WshShell.SendKeys (chr(174))

    ‘Mute toggle (keyboard press mute toggle)
    WshShell.SendKeys(chr(&hAD))

  15. Assaf Says:

    thank you very much!

Leave a Reply

.htaccess Apache article articles by Nilpo ASP ASP Free automation clipboard copy desktop Dev Shed docx Internet Explorer message box Microsoft PHP registry remove script scripting text tutorial tweak tweets Twitter UAC updates User Account Control VBS VBScript vista volume Windows Windows 7 Windows Guru Windows Script Windows Script Host Windows Scripting Windows Vista Windows XP Word WScript wscript.exe WSH XP