2008-11-01 170 views
14

試圖編寫一個PowerShell cmdlet,在開始時將靜音(除非已經靜音),並在最後取消靜音(僅當靜音時纔開始)。 找不到我可以使用的任何PoweShell或WMI對象。我正在玩弄使用Win32函數,如auxGetVolumeauxSetVolume,但無法完成它的工作(如何從IntPtr中讀取值?)。如何使PowerShell中的聲音靜音/取消靜音

我正在使用V2 CTP2。任何想法的人?

謝謝!

+0

有趣的問題! – 2008-11-01 04:04:49

+0

你見過這個問題嗎(它傾向於嘟嘟,但我不確定你在說什麼)? http://stackoverflow.com/questions/252799/turning-off-the-cmd-window-beep-sound – Ady 2008-11-01 06:48:20

回答

5

似乎沒有一種快速簡單的方法來調整音量。如果您有C++經驗,您可以使用this blog post做些事情,其中​​Larry Osterman介紹瞭如何從平臺API調用IAudioEndpointVolume接口Vista,XP可能會比我在幾次搜索中發現的更困難)。

V2確實允許您編譯內聯代碼(通過Add-Type),所以這可能是一個選項。

5

您可以通過簡單管理Windows音頻服務以另一種方式爲貓設置皮膚。停止它靜音,開始取消靜音。

+0

這是我今天在我的搜索中找到的最簡單的選項+1。 「網絡停止」Windows音頻「 – miltonb 2014-12-22 01:40:37

2

我沒有找到如何在PowerShell中做到這一點,但有一個名爲的NirCmd一個命令行實用工具,將運行以下命令做的伎倆:

C:\ utils的\ nircmd.exe mutesysvolume 2

的NirCmd可以免費在這裏: http://www.nirsoft.net/utils/nircmd.html

12

使用在PS1 PowerShell腳本以下命令:

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

vbscript中的解決方案:

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

這些鍵每次都將音量減少2。

15

從Vista開始,您必須使用Core Audio API來控制系統音量。這是一個不支持自動化的COM API,因此需要使用.NET和PowerShell中的大量樣板。

反正下面的代碼讓你訪問PowerShell中的[Audio]::Volume[Audio]::Mute屬性。這也可以在遠程計算機上工作,這可能是有用的。只需在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包裝外面的核心音頻API,如果你需要一個,但我不知道一組的PowerShell cmdlet的友好的。

附:Diogo answer看起來很聰明,但它不適合我。

2

我知道這是不是PowerShell中,但結合從邁克爾和迪奧戈的答案給出了一個單行的VBScript的解決方案:

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

摑這在mute.vbs,你可以只需雙擊切換靜音

  • 仍然wor在Windows 10 KS(10586.104)
  • 沒有,你可能會使用PowerShell
4

亞歷山大的回答適合我的情況,但他的例子並不由於編譯錯誤,工作就「變種」的命名空間需要Set-ExecutionPolicy。看起來更新/不同版本的.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:\> 
相關問題