Search code examples
c++visual-studiowinapivisual-studio-2010device

How to get a list of video capture devices (web cameras) on windows? (C++)


So we have a simple C++ win32 console app. All we want is to print list of web cameras and other video capture devices that are avaliable. We want to use windows apis as much as possible - no external libs - after all - all we want is to print out a a list - not to fly onto the moon!) How to do such thing?

My own reserch: I found this official msdn sample but I still do not get how to output device list onto screen=( (sorry - I am new to C++)

... some more reserch...

In one of simpliest ms samples on topic found this

HRESULT OnInitDialog(HWND hwnd, ChooseDeviceParam *pParam)
{
    HRESULT hr = S_OK;

    HWND hList = GetDlgItem(hwnd, IDC_DEVICE_LIST);

    // Display a list of the devices.

    for (DWORD i = 0; i < pParam->count; i++)
    {
        WCHAR *szFriendlyName = NULL;

        hr = pParam->ppDevices[i]->GetAllocatedString(
            MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,
            &szFriendlyName,
            NULL
            );

        if (FAILED(hr))
        {
            break;
        }

        int index = ListBox_AddString(hList, szFriendlyName);

        ListBox_SetItemData(hList, index, i);

        CoTaskMemFree(szFriendlyName);
    }

looks like it should do the job but I do not get how to include this into simple command line app so to output data...


also from this series:


Solution

  • From the examples shown, copy the following code into dev.c. Then open the command line with all the SDK variables set. At the command line link to ole32.lib and oleaut32.lib. It will then show you all the devices.

    cl dev.c ole32.lib oleaut32.lib

    dev.exe will give out the list on the command line.

    #include <windows.h>
    #include <dshow.h>
    
    #pragma comment(lib, "strmiids")
    
    HRESULT EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum)
    {
        // Create the System Device Enumerator.
        ICreateDevEnum *pDevEnum;
        HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,  
            CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));
    
        if (SUCCEEDED(hr))
        {
            // Create an enumerator for the category.
            hr = pDevEnum->CreateClassEnumerator(category, ppEnum, 0);
            if (hr == S_FALSE)
            {
                hr = VFW_E_NOT_FOUND;  // The category is empty. Treat as an error.
            }
            pDevEnum->Release();
        }
        return hr;
    }
    
    
    void DisplayDeviceInformation(IEnumMoniker *pEnum)
    {
        IMoniker *pMoniker = NULL;
    
        while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
        {
            IPropertyBag *pPropBag;
            HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
            if (FAILED(hr))
            {
                pMoniker->Release();
                continue;  
            } 
    
            VARIANT var;
            VariantInit(&var);
    
            // Get description or friendly name.
            hr = pPropBag->Read(L"Description", &var, 0);
            if (FAILED(hr))
            {
                hr = pPropBag->Read(L"FriendlyName", &var, 0);
            }
            if (SUCCEEDED(hr))
            {
                printf("%S\n", var.bstrVal);
                VariantClear(&var); 
            }
    
            hr = pPropBag->Write(L"FriendlyName", &var);
    
            // WaveInID applies only to audio capture devices.
            hr = pPropBag->Read(L"WaveInID", &var, 0);
            if (SUCCEEDED(hr))
            {
                printf("WaveIn ID: %d\n", var.lVal);
                VariantClear(&var); 
            }
    
            hr = pPropBag->Read(L"DevicePath", &var, 0);
            if (SUCCEEDED(hr))
            {
                // The device path is not intended for display.
                printf("Device path: %S\n", var.bstrVal);
                VariantClear(&var); 
            }
    
            pPropBag->Release();
            pMoniker->Release();
        }
    }
    
    void main()
    {
        HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
        if (SUCCEEDED(hr))
        {
            IEnumMoniker *pEnum;
    
            hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum);
            if (SUCCEEDED(hr))
            {
                DisplayDeviceInformation(pEnum);
                pEnum->Release();
            }
            hr = EnumerateDevices(CLSID_AudioInputDeviceCategory, &pEnum);
            if (SUCCEEDED(hr))
            {
                DisplayDeviceInformation(pEnum);
                pEnum->Release();
            }
            CoUninitialize();
        }
    }