winapi powershell volume mute

winapi - ¿Cómo puedo silenciar/activar el sonido de PowerShell?



volume mute (10)

No parece haber una forma rápida y fácil de ajustar el volumen. Si tiene experiencia en c ++, puede hacer algo con esta publicación de blog , donde Larry Osterman describe cómo llamar a la interfaz IAudioEndpointVolume desde la API de la plataforma (para Vista, XP puede ser más difícil de lo que he encontrado en algunas búsquedas).

V2 le permite compilar código en línea (a través de Add-Type), por lo que podría ser una opción.

Intentando escribir un cmdlet de PowerShell que silenciará el sonido al inicio, a menos que ya esté silenciado, y lo desactivará al final (solo si no fue silenciado para comenzar). No pude encontrar ningún objeto PoweShell o WMI que pudiera usar. Estuve jugando con el uso de funciones de Win32 como auxGetVolume o auxSetVolume , pero no conseguí que funcionara (¿cómo leer los valores de un IntPtr?).

Estoy usando V2 CTP2. ¿Alguna idea gente?

¡Gracias!


Podría despellejar al gato de otra manera simplemente administrando el Servicio de audio de Windows. Detener para silenciar, iniciarlo para dejar de silenciar.


No encontré cómo hacer esto en PowerShell, pero hay una utilidad de línea de comandos llamada NirCmd que hará el truco ejecutando este comando:

C: / utils / nircmd.exe mutesysvolume 2

NirCmd está disponible de forma gratuita aquí: http://www.nirsoft.net/utils/nircmd.html


Use los siguientes comandos en un script de powershell ps1:

$obj = new-object -com wscript.shell $obj.SendKeys([char]173)


Solución en vbscript:

Set WshShell = CreateObject("WScript.Shell") For i = 0 To 50 WshShell.SendKeys(chr(174)) WScript.Sleep 100 Next

Las teclas reducen el volumen en 2 cada vez.


Sé que no es PowerShell, pero la combinación de las respuestas de Michael y Diogo da una solución VBScript de una línea:

CreateObject("WScript.Shell").SendKeys(chr(173))

mute.vbs esto en mute.vbs , y solo puedes hacer doble clic para alternar mute

  • todavía funciona en Windows 10 (10586.104)
  • no es necesario Set-ExecutionPolicy como lo haría con PowerShell

La respuesta de Alexandre se ajustaba a mi situación, pero su ejemplo no funciona debido a errores de compilación con respecto al espacio de nombres de ''var''. Parece que las versiones más nuevas / diferentes de .net pueden hacer que el ejemplo no funcione. Si descubrió que recibió errores de compilación, esta es una versión alternativa para tratar esos casos:

Add-Type -Language CsharpVersion3 -TypeDefinition @'' using System.Runtime.InteropServices; [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IAudioEndpointVolume { // f(), g(), ... are unused COM method slots. Define these if you care int f(); int g(); int h(); int i(); int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext); int j(); int GetMasterVolumeLevelScalar(out float pfLevel); int k(); int l(); int m(); int n(); int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext); int GetMute(out bool pbMute); } [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDevice { int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev); } [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDeviceEnumerator { int f(); // Unused int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint); } [ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] class MMDeviceEnumeratorComObject { } public class Audio { static IAudioEndpointVolume Vol() { var enumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator; IMMDevice dev = null; Marshal.ThrowExceptionForHR(enumerator.GetDefaultAudioEndpoint(/*eRender*/ 0, /*eMultimedia*/ 1, out dev)); IAudioEndpointVolume epv = null; var epvid = typeof(IAudioEndpointVolume).GUID; Marshal.ThrowExceptionForHR(dev.Activate(ref epvid, /*CLSCTX_ALL*/ 23, 0, out epv)); return epv; } public static float Volume { get {float v = -1; Marshal.ThrowExceptionForHR(Vol().GetMasterVolumeLevelScalar(out v)); return v;} set {Marshal.ThrowExceptionForHR(Vol().SetMasterVolumeLevelScalar(value, System.Guid.Empty));} } public static bool Mute { get { bool mute; Marshal.ThrowExceptionForHR(Vol().GetMute(out mute)); return mute; } set { Marshal.ThrowExceptionForHR(Vol().SetMute(value, System.Guid.Empty)); } } } ''@

El uso es el mismo:

PS C:/> [Audio]::Volume # Check current volume (now about 10%) 0,09999999 PS C:/> [Audio]::Mute # See if speaker is muted False PS C:/> [Audio]::Mute = $true # Mute speaker PS C:/> [Audio]::Volume = 0.75 # Set volume to 75% PS C:/> [Audio]::Volume # Check that the changes are applied 0,75 PS C:/> [Audio]::Mute True PS C:/>


Comenzando con Vista, debe usar Core Audio API para controlar el volumen del sistema. Es una API COM que no es compatible con la automatización y, por lo tanto, requiere una gran cantidad de plantillas para usar desde .NET y PowerShell.

De todos modos, el código de abajo le permite acceder a las propiedades [Audio]::Volume y [Audio]::Mute de PowerShell. Esto también funciona en una computadora remota que podría ser útil. Simplemente copie y pegue el código en su ventana de PowerShell.

Add-Type -TypeDefinition @'' using System.Runtime.InteropServices; [Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IAudioEndpointVolume { // f(), g(), ... are unused COM method slots. Define these if you care int f(); int g(); int h(); int i(); int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext); int j(); int GetMasterVolumeLevelScalar(out float pfLevel); int k(); int l(); int m(); int n(); int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext); int GetMute(out bool pbMute); } [Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDevice { int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev); } [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] interface IMMDeviceEnumerator { int f(); // Unused int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint); } [ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] class MMDeviceEnumeratorComObject { } public class Audio { static IAudioEndpointVolume Vol() { var enumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator; IMMDevice dev = null; Marshal.ThrowExceptionForHR(enumerator.GetDefaultAudioEndpoint(/*eRender*/ 0, /*eMultimedia*/ 1, out dev)); IAudioEndpointVolume epv = null; var epvid = typeof(IAudioEndpointVolume).GUID; Marshal.ThrowExceptionForHR(dev.Activate(ref epvid, /*CLSCTX_ALL*/ 23, 0, out epv)); return epv; } public static float Volume { get {float v = -1; Marshal.ThrowExceptionForHR(Vol().GetMasterVolumeLevelScalar(out v)); return v;} set {Marshal.ThrowExceptionForHR(Vol().SetMasterVolumeLevelScalar(value, System.Guid.Empty));} } public static bool Mute { get { bool mute; Marshal.ThrowExceptionForHR(Vol().GetMute(out mute)); return mute; } set { Marshal.ThrowExceptionForHR(Vol().SetMute(value, System.Guid.Empty)); } } } ''@

Muestra de uso:

PS C:/> [Audio]::Volume # Check current volume (now about 10%) 0,09999999 PS C:/> [Audio]::Mute # See if speaker is muted False PS C:/> [Audio]::Mute = $true # Mute speaker PS C:/> [Audio]::Volume = 0.75 # Set volume to 75% PS C:/> [Audio]::Volume # Check that the changes are applied 0,75 PS C:/> [Audio]::Mute True PS C:/>

Hay contenedores de .NET más completos para la API Core Audio si necesita uno, pero no conozco un conjunto de cmdlets compatibles con PowerShell.

La respuesta de PS Diogo parece inteligente, pero no funciona para mí.