通过c++获取电脑的音频列表

通过c++获取电脑的音频列表

#include <windows.h>
#include <mmdeviceapi.h>
#include <functiondiscoverykeys_devpkey.h>
#include <Wbemidl.h>
#include <comdef.h>
#include <sstream>
#include <iostream>

extern "C" const PROPERTYKEY PKEY_Device_FriendlyName =
{ {0xa45c254e, 0xdf1c, 0x4efd, {0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0}}, 14 };

#pragma comment(linker, "/alternatename:_CLSID_WbemLocator=_CLSID_WbemLocator_Stub")
#pragma comment(linker, "/alternatename:_IID_IWbemLocator=_IID_IWbemLocator_Stub")

extern "C" {
    const CLSID CLSID_WbemLocator_Stub = {0x4590f811,0x1d3a,0x11d0,{0x89,0x1f,0x00,0xaa,0x00,0x4b,0x2e,0x24}};
    const IID   IID_IWbemLocator_Stub  = {0xdc12a687,0x737f,0x11cf,{0x88,0x4d,0x00,0xaa,0x00,0x4b,0x2e,0x24}};
}

static std::string BstrToUtf8(BSTR b)
{
    if (!b) return "";
    int len = WideCharToMultiByte(CP_UTF8,0,b,-1,nullptr,0,nullptr,nullptr);
    std::string s(len,'\0');
    WideCharToMultiByte(CP_UTF8,0,b,-1,&s[0],len,nullptr,nullptr);
    return s;
}


static std::string QueryWMI(const std::wstring& wql,const std::wstring& prop)
{
    std::string result;
    HRESULT hr;
    hr = CoInitializeEx(nullptr,COINIT_MULTITHREADED);
    if(FAILED(hr)) return result;
    hr = CoInitializeSecurity(nullptr,-1,nullptr,nullptr,
                              RPC_C_AUTHN_LEVEL_DEFAULT,
                              RPC_C_IMP_LEVEL_IMPERSONATE,
                              nullptr,EOAC_NONE,nullptr);
    if(FAILED(hr)&&hr!=RPC_E_TOO_LATE){CoUninitialize();return result;}

    IWbemLocator* pLoc=nullptr;
    hr=CoCreateInstance(CLSID_WbemLocator,nullptr,CLSCTX_INPROC_SERVER,
                        IID_IWbemLocator,(void**)&pLoc);
    if(FAILED(hr)){CoUninitialize();return result;}

    IWbemServices* pSvc=nullptr;
    hr=pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"),nullptr,nullptr,
                           nullptr,0,nullptr,nullptr,&pSvc);
    if(SUCCEEDED(hr)){
        CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,
                          nullptr,RPC_C_AUTHN_LEVEL_CALL,
                          RPC_C_IMP_LEVEL_IMPERSONATE,nullptr,EOAC_NONE);
        IEnumWbemClassObject* pEnum=nullptr;
        hr=pSvc->ExecQuery(_bstr_t(L"WQL"),_bstr_t(wql.c_str()),
                           WBEM_FLAG_FORWARD_ONLY,nullptr,&pEnum);
        if(SUCCEEDED(hr)){
            IWbemClassObject* obj=nullptr;ULONG cnt=0;
            if(pEnum->Next(WBEM_INFINITE,1,&obj,&cnt)==S_OK){
                VARIANT v;
                obj->Get(prop.c_str(),0,&v,nullptr,nullptr);
                result=BstrToUtf8(v.bstrVal);
                VariantClear(&v);
                obj->Release();
            }
            pEnum->Release();
        }
        pSvc->Release();
    }
    pLoc->Release();
    CoUninitialize();
    return result;
}


static std::string BuildAudioTable()
{
    CoInitialize(nullptr);
    IMMDeviceEnumerator* pEnum=nullptr;
    CoCreateInstance(__uuidof(MMDeviceEnumerator),nullptr,
                     CLSCTX_ALL,__uuidof(IMMDeviceEnumerator),
                     (void**)&pEnum);

    std::wstringstream ss;
    ss<<L"id\ttype\tname\n";

    auto dump=[&](EDataFlow dir,const wchar_t* type){
        IMMDeviceCollection* coll=nullptr;
        if(SUCCEEDED(pEnum->EnumAudioEndpoints(dir,DEVICE_STATE_ACTIVE,&coll))){
            UINT n=0; coll->GetCount(&n);
            static int id=1;
            for(UINT i=0;i<n;++i){
                IMMDevice* dev=nullptr; coll->Item(i,&dev);
                IPropertyStore* ps=nullptr; dev->OpenPropertyStore(STGM_READ,&ps);
                PROPVARIANT v; PropVariantInit(&v);
                ps->GetValue(PKEY_Device_FriendlyName,&v);
                ss<<id++<<L'\t'<<type<<L'\t'<<v.pwszVal<<L'\n';
                PropVariantClear(&v);
                ps->Release(); dev->Release();
            }
            coll->Release();
        }
    };
    dump(eCapture,L"输入设备");
    dump(eRender, L"输出设备");
    pEnum->Release();
    CoUninitialize();
    return BstrToUtf8(const_cast<BSTR>(ss.str().c_str()));
}


int main()
{
    SetConsoleOutputCP(CP_UTF8);
    std::ios::sync_with_stdio(false);

    std::cout<<"======== 音频设备 ========\n"<<BuildAudioTable()<<'\n';
    std::cout<<"主板序列号: "<<QueryWMI(L"SELECT SerialNumber FROM Win32_BaseBoard",L"SerialNumber")<<'\n';
    std::cout<<"CPU ID:     "<<QueryWMI(L"SELECT ProcessorId FROM Win32_Processor",L"ProcessorId")<<'\n';
    return 0;
}
© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容