控制其他应用程序的音量

时间:2009-11-24 16:49:41

标签: com windows-7 audio core-audio

我正在尝试使用Windows 7音频API制作一个控制其他进程量的应用。

我正在寻找的是其他进程使用的会话的ISimpleAudioVolume

我已尝试使用IAudioSessionEnumerator,但它只会给我IAudioSessionControl2会话。使用IAudioSessionControl我设法通过sndvol更改音量而不是自己更改音量时收到通知。

我也尝试过使用IAudioSessionManager中的GetSimpleAudioVolume(),但它只会在当前进程中为我提供会话。

你是怎么做到的?应该可以,因为sndvol正在这样做。

3 个答案:

答案 0 :(得分:1)

以下是使用Core Audio API静音另一个进程的示例。

#include <windows.h>
#include <iostream>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include <Audiopolicy.h>
#include <comdef.h>
#include <comip.h>

#define CHECK_HR(hr)   \
    if(FAILED(hr)) {    \
        std::cout << "error" << std::endl;   \
        return 0;   \
                }
_COM_SMARTPTR_TYPEDEF(IMMDevice, __uuidof(IMMDevice));
_COM_SMARTPTR_TYPEDEF(IMMDeviceEnumerator, __uuidof(IMMDeviceEnumerator));
_COM_SMARTPTR_TYPEDEF(IAudioSessionManager2, __uuidof(IAudioSessionManager2));
_COM_SMARTPTR_TYPEDEF(IAudioSessionManager2, __uuidof(IAudioSessionManager2));
_COM_SMARTPTR_TYPEDEF(IAudioSessionEnumerator, __uuidof(IAudioSessionEnumerator));
_COM_SMARTPTR_TYPEDEF(IAudioSessionControl2, __uuidof(IAudioSessionControl2));
_COM_SMARTPTR_TYPEDEF(IAudioSessionControl, __uuidof(IAudioSessionControl));
_COM_SMARTPTR_TYPEDEF(ISimpleAudioVolume, __uuidof(ISimpleAudioVolume));

IAudioSessionManager2Ptr CreateSessionManager()
{
    HRESULT hr = S_OK;

    IMMDevicePtr pDevice;
    IMMDeviceEnumeratorPtr pEnumerator;
    IAudioSessionManager2Ptr pSessionManager;


    // Create the device enumerator.
    CHECK_HR(hr = CoCreateInstance(
        __uuidof(MMDeviceEnumerator),
        NULL, CLSCTX_ALL,
        __uuidof(IMMDeviceEnumerator),
        (void**)&pEnumerator));

    // Get the default audio device.
    CHECK_HR(hr = pEnumerator->GetDefaultAudioEndpoint(
        eRender, eConsole, &pDevice));

    // Get the session manager.
    CHECK_HR(hr = pDevice->Activate(
        __uuidof(IAudioSessionManager2), CLSCTX_ALL,
        NULL, (void**)&pSessionManager));

    return pSessionManager;
}

bool MuteProcess(DWORD processId) {

    IAudioSessionManager2Ptr mgr = CreateSessionManager();
    if (!mgr) {
        return false;
    }
    IAudioSessionEnumeratorPtr enumerator;
    if (SUCCEEDED(mgr->GetSessionEnumerator(&enumerator))) {
        int sessionCount;
        if (SUCCEEDED(enumerator->GetCount(&sessionCount))) {
            for (int i = 0; i < sessionCount; i++) {
                IAudioSessionControlPtr control;
                if (SUCCEEDED(enumerator->GetSession(i, &control))) {
                    IAudioSessionControl2Ptr control2;
                    if (SUCCEEDED(control->QueryInterface(__uuidof(IAudioSessionControl2), (void**)&control2))) {
                        DWORD foundProcessId;
                        if (SUCCEEDED(control2->GetProcessId(&foundProcessId))) {
                            if (foundProcessId == processId) {
                                ISimpleAudioVolumePtr volume;
                                if (SUCCEEDED(control2->QueryInterface(_uuidof(ISimpleAudioVolume), (void**)&volume))) {
                                    if (SUCCEEDED(volume->SetMute(TRUE, 0))) {
                                        return true;
                                    }
                                }
                            }
                        }

                    }

                }
            }
        }
    }
    return false;
}

int _tmain(int argc, _TCHAR* argv[]){
    CoInitialize(NULL);
    DWORD processId = 11944;
    MuteProcess(processId);

    return 0;
}

答案 1 :(得分:0)

关于这个问题有一个MSDN forum questionBlog Post。希望这会有所帮助。

答案 2 :(得分:0)

根据Larry Osterman的说法

  

“没有公开记录的机制可以做你正在尝试做的事情。”