2008-11-01 8 views
14

Tratando de 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 se enmudeció para comenzar con) 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?).Cómo puedo silenciar/activar el sonido de PowerShell

Estoy usando V2 CTP2. ¿Alguna idea gente?

Gracias!

+0

una pregunta interesante! –

+0

¿Has visto esta pregunta (se debe a un pitido, pero no estoy seguro de qué sonidos estás hablando)? http://stackoverflow.com/questions/252799/turning-off-the-cmd-window-beep-sound – Ady

Respuesta

5

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

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

5

Puede desollar al gato de otra manera simplemente administrando el servicio de audio de Windows. Detener para silenciar, iniciarlo para dejar de silenciar.

+0

Esta es la opción más simple que encontré en mi búsqueda hoy +1. "net stop" Windows Audio " – miltonb

+1

En PowerShell: Stop-Service-DisplayNombre" Windows Audio "& Start-Service -DisplayName" Windows Audio ". Ojalá hubiera pensado en eso antes. – Bewc

2

no he encontrado la manera de hacer esto en PowerShell, pero hay una utilidad de línea de comandos llamada NirCmd que va a hacer el truco mediante la ejecución de este comando:

C: \ utils \ nircmd.exe mutesysvolume 2

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

12

utilizar los siguientes comandos en un script de PowerShell PS1:

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

Para ejecutar con .bat coloca este código dentro del archivo y escritura ** powershell.exe -file "C: \ file.ps1" ** –

2

Solución en VBScript:

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

Las teclas de reducir el volumen 2 cada vez.

15

Comenzando con Vista, tiene que usar el 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)); } 
    } 
} 
'@ 

Ejemplo 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 envoltorios de .NET más completos que hay para la API de Core Audio, si lo necesita, pero no estoy al tanto de un conjunto de cmdlets de PowerShell amigables.

P.S.Diogo answer parece inteligente pero no funciona para mí.

2

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

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

palmada de este en mute.vbs, y puede simplemente hacer doble clic para alternar mute

  • todavía wor ks en Windows 10 (10586.104)
  • hay necesidad de Set-ExecutionPolicy como puede ser que con PowerShell
4

respuesta de Alexandre se ajusta a mi situación, pero su ejemplo no funciona debido a errores de compilación en relación con el espacio de nombres de 'var'. Parece que las versiones más nuevas/diferentes de .net pueden hacer que el ejemplo no funcione. Si has encontrado que ha recibido errores de compilación, se trata de una versión alternativa de probar para aquellos 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:\> 
Cuestiones relacionadas