Как отключить / отключить звук из PowerShell

попытка написать командлет PowerShell, который отключит звук при запуске, если он уже не отключен, и отключит его в конце (только если он не был отключен с самого начала). Не удалось найти объект PoweShell или WMI, который я мог бы использовать. Я играл с использованием функций Win32, таких как auxGetVolume или auxSetVolume, но не смог заставить его работать (как читать значения из IntPtr?).

Я использую V2 в версии ctp2. Есть идеи, ребята?

спасибо!

10 ответов


кажется, что нет быстрого и простого способа регулировки громкости.. Если у вас есть опыт c++, вы можете что-то сделать с этот блог, где Ларри Остерман описывает, как вызвать интерфейс IAudioEndpointVolume из api платформы(для Vista XP может быть сложнее из того, что я нашел в нескольких поисках).

V2 позволяет компилировать встроенный код (через Add-Type), так что это может быть опция.


начиная с Vista, вы должны использовать Core Audio API для управления громкостью системы. Это COM API, который не поддерживает автоматизацию и, следовательно, требует много шаблонных шаблонов для использования из .NET и PowerShell.

в любом случае, код ниже позволит вам доступ к [Audio]::Volume и [Audio]::Mute свойства из PowerShell. Это также работает на удаленном компьютере, который может быть полезен. Просто скопируйте и вставьте код в окно 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)); }
  }
}
'@

использование пример:

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:\>

есть более полные .NET-оболочки для Core Audio API, если вам нужен один, но я не знаю набора командлетов PowerShell friendly.

П. С. Diogo ответ вроде умная, но это не работает для меня.


используйте следующие команды в сценарии powershell ps1:

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

вы можете снять кожу с кошки другим способом, просто управляя службой Windows Audio. Остановите его для отключения звука, запустите его для включения.


Если вы можете сделать это в C# вы можете сделайте это в PowerShell.


ответ Александра соответствует моей ситуации, но его пример не работает из-за ошибок компиляции относительно пространства имен "var". Кажется, что более новые / разные версии .net могут привести к тому, что пример не будет работать. Если вы обнаружили, что получили ошибки компиляции, это альтернативная версия для этих случаев:

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)); }
  }
}
'@

использование:

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:\>

Я не нашел, как это сделать в PowerShell, но есть утилита командной строки под названием NirCmd, которая сделает трюк, выполнив эту команду:

C:\utils\nircmd.exe mutesysvolume 2

NirCmd доступен бесплатно здесь: http://www.nirsoft.net/utils/nircmd.html


решение в vbscript:

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

клавиши уменьшают громкость на 2 каждый раз.


Я знаю, что это не PowerShell, но объединение ответов от Michael и Diogo дает однострочное решение VBScript:

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

плевок в mute.vbs, и вы можете просто дважды щелкнуть, чтобы переключить mute

  • все еще работает в Windows 10 (10586.104)
  • не нужно Set-ExecutionPolicy Как вы могли бы с PowerShell

проверить мой ответ изменить уровень звука из powershell?

Set-DefaultAudioDeviceMute