裝置屬性 (核心音訊 API)

在列舉 音頻端點裝置的過程中,用戶端應用程式可以詢問其裝置屬性的端點物件。 裝置屬性會在 MMDevice API 的 IPropertyStore 介面實作中公開。 假設端點物件的 IMMDevice 介面參考,用戶端可以藉由呼叫 IMMDevice::OpenPropertyStore 方法,來取得端點對象屬性存放區的參考。

用戶端可以讀取這些屬性,但不應該加以設定。 屬性值會儲存為 PROPVARIANT 結構。

端點管理員會設定端點的基本裝置屬性。 端點管理員是負責偵測音訊端點裝置是否存在的 Windows 元件。

下列清單中的每個PKEY_Xxx屬性標識碼都是 PROPERTYKEY 類型的常數,定義於頭檔Functiondiscoverykeys_devpkey.h 中。 所有音訊端點裝置都有這些裝置屬性。

屬性 說明
PKEY_DeviceInterface_FriendlyName 端點裝置所連接的音訊配接器的易記名稱(例如,“XYZ 音訊配接器”)。
PKEY_Device_DeviceDesc 端點裝置的裝置描述(例如「說話者」)。
PKEY_Device_FriendlyName 端點裝置的易記名稱(例如「喇叭(XYZ 音訊配接器)」。
PKEY_Device_InstanceId 儲存音訊端點 裝置實例標識碼。 您也可以透過 IMMDevice::GetId 方法取得此值。 如需此屬性的詳細資訊,請參閱 端點標識符字串DEVPKEY_Device_InstanceId
PKEY_Device_ContainerId 儲存 實作音訊端點之 PnP 裝置的容器標識碼 。 如需此屬性的詳細資訊,請參閱 DEVPKEY_Device_ContainerId

某些音訊端點裝置可能有其他屬性未出現在上述清單中。 如需其他屬性的詳細資訊,請參閱 音訊端點屬性

如需 PROPERTYKEY 的詳細資訊,請參閱 Windows 屬性系統檔

下列程式代碼範例會列印系統中所有音訊轉譯端點裝置的顯示名稱:

//-----------------------------------------------------------
// This function enumerates all active (plugged in) audio
// rendering endpoint devices. It prints the friendly name
// and endpoint ID string of each endpoint device.
//-----------------------------------------------------------
#define EXIT_ON_ERROR(hres)  \
              if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk)  \
              if ((punk) != NULL)  \
                { (punk)->Release(); (punk) = NULL; }

const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);

void PrintEndpointNames()
{
    HRESULT hr = S_OK;
    IMMDeviceEnumerator *pEnumerator = NULL;
    IMMDeviceCollection *pCollection = NULL;
    IMMDevice *pEndpoint = NULL;
    IPropertyStore *pProps = NULL;
    LPWSTR pwszID = NULL;

    hr = CoCreateInstance(
           CLSID_MMDeviceEnumerator, NULL,
           CLSCTX_ALL, IID_IMMDeviceEnumerator,
           (void**)&pEnumerator);
    EXIT_ON_ERROR(hr)

    hr = pEnumerator->EnumAudioEndpoints(
                        eRender, DEVICE_STATE_ACTIVE,
                        &pCollection);
    EXIT_ON_ERROR(hr)

    UINT  count;
    hr = pCollection->GetCount(&count);
    EXIT_ON_ERROR(hr)

    if (count == 0)
    {
        printf("No endpoints found.\n");
    }

    // Each loop prints the name of an endpoint device.
    for (ULONG i = 0; i < count; i++)
    {
        // Get pointer to endpoint number i.
        hr = pCollection->Item(i, &pEndpoint);
        EXIT_ON_ERROR(hr)

        // Get the endpoint ID string.
        hr = pEndpoint->GetId(&pwszID);
        EXIT_ON_ERROR(hr)
        
        hr = pEndpoint->OpenPropertyStore(
                          STGM_READ, &pProps);
        EXIT_ON_ERROR(hr)

        PROPVARIANT varName;
        // Initialize container for property value.
        PropVariantInit(&varName);

        // Get the endpoint's friendly-name property.
        hr = pProps->GetValue(
                       PKEY_Device_FriendlyName, &varName);
        EXIT_ON_ERROR(hr)

        // GetValue succeeds and returns S_OK if PKEY_Device_FriendlyName is not found.
        // In this case vartName.vt is set to VT_EMPTY.      
        if (varName.vt != VT_EMPTY)
        {
            // Print endpoint friendly name and endpoint ID.
            printf("Endpoint %d: \"%S\" (%S)\n", 
                    i, varName.pwszVal, pwszID);
        }

        CoTaskMemFree(pwszID);
        pwszID = NULL;
        PropVariantClear(&varName);
        SAFE_RELEASE(pProps)
        SAFE_RELEASE(pEndpoint)
    }
    SAFE_RELEASE(pEnumerator)
    SAFE_RELEASE(pCollection)
    return;

Exit:
    printf("Error!\n");
    CoTaskMemFree(pwszID);
    SAFE_RELEASE(pEnumerator)
    SAFE_RELEASE(pCollection)
    SAFE_RELEASE(pEndpoint)
    SAFE_RELEASE(pProps)
}

上述程式代碼範例中的 FAILED 宏定義於頭檔 Winerror.h 中。

在上述程式代碼範例中,PrintEndpointNames 函式中的 for-loop 主體會呼叫 IMMDevice::GetId 方法,以取得 IMMDevice 介面實例所代表音頻端點裝置的端點標識符字串。 字串會唯一識別系統中所有其他音訊端點裝置的裝置。 用戶端可以使用端點標識符字串,在稍後或呼叫 IMMDeviceEnumerator::GetDevice 方法,在不同的進程中建立音頻端點裝置的實例。 用戶端應將端點標識符字串的內容視為不透明。 也就是說,客戶端不應該嘗試剖析字串的內容,以取得裝置的相關信息。 原因是字串格式未定義,而且可能會從MMDevice API的其中一個實作變更為下一個。

上述程式代碼範例中 PrintEndpointNames 函式取得的易記裝置名稱和端點標識符字串,與 DirectSound 在裝置列舉期間提供的易記裝置名稱和端點標識符字元串相同。 如需詳細資訊,請參閱 舊版音訊應用程式的音訊事件。

在上述程式代碼範例中,PrintEndpointNames 函式會呼叫 CoCreateInstance 函式,為系統中的音訊端點裝置建立列舉值。 除非先前呼叫 CoInitialize 或 CoInitializeEx 函式來初始化 COM 連結庫的呼叫程式,否則 CoCreateInstance 呼叫將會失敗。 如需 CoCreateInstance、CoInitialize 和 CoInitializeEx 的詳細資訊,請參閱 Windows SDK 檔。

如需 IMMDeviceEnumerator、IMMDeviceCollectionIMMDevice 介面的詳細資訊,請參閱 MMDevice API

音訊端點裝置