Как отключить звук/отключить звук от PowerShell
Попытка написать командлет PowerShell, который отключит звук при запуске, если он уже не отключен, и отключить его в конце (только если он не был отключен для начала).
Не удалось найти объект PoweShell или WMI, который я мог бы использовать. Я играл с использованием функций Win32, таких как auxGetVolume или auxSetVolume, но не мог заставить его работать (как читать значения из IntPtr?).
Я использую V2 CTP2. Любые идеи людей?
Спасибо!
Ответы
Ответ 1
Кажется, что нет быстрого и простого способа регулировки громкости. Если у вас есть опыт работы на С++, вы можете что-то сделать с этот пост в блоге, где Ларри Остерман описывает, как вызвать интерфейс IAudioEndpointVolume с платформы api (для Vista XP может быть сложнее из того, что я нашел в нескольких поисках).
V2 позволяет вам скомпилировать встроенный код (через Add-Type), так что это может быть вариант.
Ответ 2
Начиная с 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.
P.S. Ответ Diogo кажется умным, но он не работает для меня.
Ответ 3
Используйте следующие команды в powershell ps1 script:
$obj = new-object -com wscript.shell
$obj.SendKeys([char]173)
Ответ 4
Вы можете обмануть кошку другим способом, просто управляя Службой Windows Audio. Остановите его, чтобы отключить звук, и включите его.
Ответ 5
Если вы можете сделать это в С#, вы можете сделать это в PowerShell.
Ответ 6
Ответ Alexandre соответствует моей ситуации, но его пример не работает из-за ошибок компиляции в отношении пространства имен '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:\>
Ответ 7
Я не нашел, как это сделать в PowerShell, но есть утилита командной строки под названием NirCmd, которая будет делать трюк, выполнив эту команду:
C:\utils\nircmd.exe mutesysvolume 2
NirCmd можно бесплатно скачать здесь:
http://www.nirsoft.net/utils/nircmd.html
Ответ 8
Решение в vbscript:
Set WshShell = CreateObject("WScript.Shell")
For i = 0 To 50
WshShell.SendKeys(chr(174))
WScript.Sleep 100
Next
Клавиши уменьшают громкость на 2 каждый раз.
Ответ 9
Я знаю, что это не PowerShell, но объединение ответов от Michael и Diogo дает однострочное решение VBScript:
CreateObject("WScript.Shell").SendKeys(chr(173))
Поместите это в mute.vbs
, и вы можете просто дважды щелкнуть, чтобы переключиться без звука
- все еще работает в Windows 10 (10586.104)
- не нужно
Set-ExecutionPolicy
, как вы могли бы с PowerShell
Ответ 10
Посмотрите мой ответ на Изменить уровень звука из PowerShell?
Set-DefaultAudioDeviceMute