VC++打开或关闭目标进程的声音(扬声器)(附源码)

Posted dvlinker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC++打开或关闭目标进程的声音(扬声器)(附源码)相关的知识,希望对你有一定的参考价值。

VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931        本文讲述如何将某个进程的声音(扬声器)打开或关闭掉,这个功能在某些场合下可能会用到,在此给大家做个分享。

1、在系统设置页面中将进程的扬声器打开或关闭

        以Win10系统为例,在系统桌面的右下角托盘图标区域中找到系统音量图标,右键点击该图标,弹出如下的右键菜单:

点击“打开音量合成器”菜单项,打开使用扬声器的进程列表页面,如下所示:

以操作企业微信进程为例,点击下面的声音图标,即可将企业微信进程的扬声器关闭或打开。如果将企业微信进程的扬声器关闭,则听不到企业微信进程的所有声音。

注意,这个地方是关闭单个进程的声音,不是关闭系统的扬声器(将扬声器的音量设置为0)!

2、通过代码实现进程扬声器打开或关闭

        Windows系统支持以COM组件的方式访问系统中的音视频设备,我们可以先获取所有的音频播放设备,然后遍历设备下对应的进程列表,然后通过进程id去遍历进程列表,找到目标进程后,对进程的扬声器进行关闭和打开操作。

         以开关本进程的扬声器为例,完整的实现代码如下:

BOOL SetCurrentSpeakerMute(BOOL bQuiet)

    HRESULT hr = S_OK;
    IMMDeviceCollection *pMultiDevice = NULL;
    IMMDevice *pDevice = NULL;
    IAudiosessionEnumerator *pSessionEnum = NULL;
    IAudioSessionManager2 *pASManager = NULL;
    IMMDeviceEnumerator *pEnumerator = NULL;
    const IID IID_ISimpleAudioVolume = __uuidof(ISimpleAudioVolume);
    const IID IID_IAudioSessionControl2 = __uuidof(IAudioSessionControl2);
 
    CoInitialize(NULL);

    // Get enumerator for audio endpoint devices.
    hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
        NULL, CLSCTX_ALL,
        __uuidof(IMMDeviceEnumerator),
        (void**)&pEnumerator);
    if (FAILED(hr))
        return FALSE;

    // 1、获取音频播放设备
    hr = pEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pMultiDevice);
    
    if (FAILED(hr))
        return FALSE;

    UINT deviceCount = 0;
    hr = pMultiDevice->GetCount(&deviceCount);
    if (FAILED(hr))
        return FALSE;

    // 2、遍历音频播放设备
    for (UINT ii = 0; ii < deviceCount; ii++)
    
        pDevice = NULL;
        hr = pMultiDevice->Item(ii, &pDevice);
        if (FAILED(hr))
            return FALSE;

        hr = pDevice->Activate(__uuidof(IAudioSessionManager), CLSCTX_ALL, NULL, (void**)&pASManager);
        if (FAILED(hr))
            return FALSE;

        hr = pASManager->GetSessionEnumerator(&pSessionEnum);
        if (FAILED(hr))
            return FALSE;

        int nCount;
        hr = pSessionEnum->GetCount(&nCount);
        for (int i = 0; i < nCount; i++)
        
            IAudioSessionControl *pSessionCtrl;
            hr = pSessionEnum->GetSession(i, &pSessionCtrl);
            if (FAILED(hr))
                continue;
            // 3、获取音频播放控制对象
            IAudioSessionControl2 *pSessionCtrl2;
            hr = pSessionCtrl->QueryInterface(IID_IAudioSessionControl2, (void **)&pSessionCtrl2);
            if (FAILED(hr))
                continue;

            ULONG pid;
            hr = pSessionCtrl2->GetProcessId(&pid);
            if (FAILED(hr))
                continue;

            ISimpleAudioVolume *pSimplevol;
            hr = pSessionCtrl2->QueryInterface(IID_ISimpleAudioVolume, (void **)&pSimplevol);
            if (FAILED(hr))
                continue;

            // 4、对比获取音频播放控制对象的进程id,判断是不是本进程的
            if (pid == GetCurrentProcessId())
            
                // 将目标进程静音
                pSimplevol->SetMute(bQuiet, &GUID_NULL);
            

            if (pSimplevol != NULL)
            
                pSimplevol->Release();
            

            if (pSessionCtrl2 != NULL)
            
                pSessionCtrl2->Release();
            

            if (pSessionCtrl != NULL)
            
                pSessionCtrl->Release();
            
        
    

    if (pSessionEnum != NULL) pSessionEnum->Release();
    if (pASManager != NULL) pASManager->Release();
    if (pDevice != NULL) pDevice->Release();
    if (pMultiDevice != NULL) pMultiDevice->Release();
    if (pEnumerator != NULL) pEnumerator->Release();
    
    CoUninitialize();
    return TRUE;

       此外,获取当前进程的静音状态的代码如下: 

BOOL GetCurrentSpeakerMuteStatus()

	BOOL bQuiet = FALSE;
	HRESULT hr = S_OK;
	IMMDeviceCollection *pMultiDevice = NULL;
	IMMDevice *pDevice = NULL;
	IAudioSessionEnumerator *pSessionEnum = NULL;
	IAudioSessionManager2 *pASManager = NULL;
	IMMDeviceEnumerator *pEnumerator = NULL;
	const IID IID_ISimpleAudioVolume = __uuidof(ISimpleAudioVolume);
	const IID IID_IAudioSessionControl2 = __uuidof(IAudioSessionControl2);

	CoInitialize(NULL);

	// Get enumerator for audio endpoint devices.
	hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
		NULL, CLSCTX_ALL,
		__uuidof(IMMDeviceEnumerator),
		(void**)&pEnumerator);
	if (FAILED(hr))
		return FALSE;

	hr = pEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pMultiDevice);
	if (FAILED(hr))
		return FALSE;

	UINT deviceCount = 0;
	hr = pMultiDevice->GetCount(&deviceCount);
	if (FAILED(hr))
		return FALSE;

	for (UINT ii = 0; ii < deviceCount; ii++)
	
		pDevice = NULL;
		hr = pMultiDevice->Item(ii, &pDevice);
		if (FAILED(hr))
			return FALSE;

		hr = pDevice->Activate(__uuidof(IAudioSessionManager), CLSCTX_ALL, NULL, (void**)&pASManager);
		if (FAILED(hr))
			return FALSE;

		hr = pASManager->GetSessionEnumerator(&pSessionEnum);
		if (FAILED(hr))
			return FALSE;

		int nCount;
		hr = pSessionEnum->GetCount(&nCount);
		for (int i = 0; i < nCount; i++)
		
			IAudioSessionControl *pSessionCtrl;
			hr = pSessionEnum->GetSession(i, &pSessionCtrl);
			if (FAILED(hr))
				continue;

			IAudioSessionControl2 *pSessionCtrl2;
			hr = pSessionCtrl->QueryInterface(IID_IAudioSessionControl2, (void **)&pSessionCtrl2);
			if (FAILED(hr))
				continue;

			ULONG pid;
			hr = pSessionCtrl2->GetProcessId(&pid);
			if (FAILED(hr))
				continue;

			ISimpleAudioVolume *pSimplevol;
			hr = pSessionCtrl2->QueryInterface(IID_ISimpleAudioVolume, (void **)&pSimplevol);
			if (FAILED(hr))
				continue;

            // 获取静音状态
			if (pid == GetCurrentProcessId())
			
				pSimplevol->GetMute(&bQuiet);
			
		
	

	pEnumerator->Release();

	return bQuiet;

以上是关于VC++打开或关闭目标进程的声音(扬声器)(附源码)的主要内容,如果未能解决你的问题,请参考以下文章

VC++判断目标文件是否被独占(附源码)

VC++ 获取窗口的类名和窗口所属进程线程id(附源码)

ubuntu中的多个扬声器多个声音[关闭]

在某些扬声器上播放声音-c ++ [关闭]

VC++如何通过代码自动弹出Windows系统的一些窗口(附源码)

VC++如何实时监测另一个进程是否已经退出?(附源码)