windows 7/10静音、音量设置 C# .Net Core

2022-05-07  乐帮网

c# windows

使用Windows API控制系统音量及静音,经过测试和网上搜索一些资料发现坑有点多。所以做一些总结和讲述。本篇提供的解决方案兼容windows7/10 32bit和64bit,结尾还做了一个小小的demo,欢迎大家指正。经过总结目前有三种解决方案:

(1)使用快捷键方式,这也是我最初想到的方式,windows 是有静音的快捷键的,所以理论上只要模拟相应的按键就可以实现功能,同理也有音量大小快捷键。但是在windows10中发现不行,主要是受限于相关运行权限和状态的限制。如果是运行于后台的服务就别想了,示例代码如下:

[DllImport("coredll.dll", SetLastError = true)]
    static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

    byte VK_VOLUME_MUTE = 0xAD;
    const int KEYEVENTF_KEYUP = 0x2;
    const int KEYEVENTF_KEYDOWN = 0x0;
    private void button1_Click(object sender, EventArgs e)
    {
            keybd_event(VK_VOLUME_MUTE, 0, KEYEVENTF_KEYDOWN, 0);
            keybd_event(VK_VOLUME_MUTE, 0, KEYEVENTF_KEYUP, 0);
    }

所有快捷键的参考:https://docs.microsoft.com/zh-cn/dotnet/api/system.consolekey?view=net-6.0

(2)使用winmm.dll方案,功能强大,稳定可靠,但是只能用于windows xp,所以说已经基本过时,详细可参考我的文章:

https://lebang2020.cn/details/2204293r34eur2.html

(3)使用User32.dll方案,兼容windows7和windows10,windows11我还没有测试,理论上也没有问题。但是这个方案呢,网上有很多代码,诸多的误导,以致于实现不了功能,下面我给一段常见的代码,代码是没有问题,但是也有一点坑后面会讲到。

中文代码地址:https://www.cnblogs.com/sjcatsoft/archive/2009/02/25/1398146.html 原文是英文地址,目前找不到了

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);

const uint WM_APPCOMMAND = 0x319;
const uint APPCOMMAND_VOLUME_UP = 0x0a;
const uint APPCOMMAND_VOLUME_DOWN = 0x09;
const uint APPCOMMAND_VOLUME_MUTE = 0x08;
//提高音量
SendMessage(this.Handle, WM_APPCOMMAND, 0x30292, APPCOMMAND_VOLUME_UP * 0x10000);
//降低音量
SendMessage(this.Handle, WM_APPCOMMAND, 0x30292, APPCOMMAND_VOLUME_DOWN * 0x10000);
//静音与恢复(执行2次恢复原状态)
SendMessage(this.Handle, WM_APPCOMMAND, 0x200eb0, APPCOMMAND_VOLUME_MUTE * 0x10000);

或者这里的代码:https://www.displayfusion.com/ScriptedFunctions/View/?ID=3bd903c6-4bdb-4c30-b479-06ff7d612ed0

using System;
using System.Drawing;
using System.Runtime.InteropServices;

public static class DisplayFusionFunction
{
    [DllImport("user32.dll")] 
    public static extern IntPtr SendMessageW(IntPtr hWnd,int Msg,IntPtr wParam,IntPtr lParam);

    private const int WM_APPCOMMAND=0x319;

    private const int APPCOMMAND_MICROPHONE_VOLUME_MUTE=0x180000;

	public static void Run(IntPtr windowHandle)
	{
		SendMessageW(windowHandle, WM_APPCOMMAND, windowHandle, (IntPtr)APPCOMMAND_MICROPHONE_VOLUME_MUTE);
	}
}

以上代码写的都没有问题挺好的,唯一的注意点在这个windowHandle,它的意思是句柄,如果你还不了解句柄可以参考我的文章:
https://lebang2020.cn/details/220505m2ko454a.html

一个通用的写法获取当前程序句柄如下:

Process currentProcess = Process.GetCurrentProcess();
SendMessageW(currentProcess.Handle, WM_APPCOMMAND, windowHandle, (IntPtr)APPCOMMAND_MICROPHONE_VOLUME_MUTE);

最后剩下一个问题,如果我是在Windows 服务中或者使用 Web Host程序等没有窗体界面的主程序,那么你会遇到问题,这就是一个严重的问题,因为权限问题,当前方法根本不会生效。所以需要需要有一个通用的强大的方法来解决这个问题。于是我自己写了一个方案并附上代码示例如下:

链接:https://pan.baidu.com/s/1lK9Zj0BO-raGrsisoF5Zvg 

一个控制台程序,按下 s 键后再按回车就会切换静音模式,按e键后按回车会退出程序。
提取码见下方。

 

(4)可以使用com组件来实现这个功能,经过测试也是比较稳定可靠的。可参考我的文章:https://lebang2020.cn/details/220512hdouo3y1.html

公众号二维码

关注我的微信公众号
在公众号里留言交流
投稿邮箱:1052839972@qq.com

庭院深深深几许?杨柳堆烟,帘幕无重数。
玉勒雕鞍游冶处,楼高不见章台路。
雨横风狂三月暮。门掩黄昏,无计留春住。
泪眼问花花不语,乱红飞过秋千去。

欧阳修

付款二维码

如果感觉对您有帮助
欢迎向作者提供捐赠
这将是创作的最大动力