1
votes

I'm trying to write a program that transfers images and videos from a camera (for my personal use, on Win 8.1). I'm using Microsoft's example code as a starting point (WIA Tutorial), and I've hit a wall trying to detect connected camera devices. The problem is that there are no errors and the code seems to work, but it just doesn't detect any connected camera (I've tried with two different cameras), while the camera is clearly detected by the OS (shows up in Windows Explorer).

Am I missing something? Is IWiaDevMgr2::EnumDeviceInfo not the way to detect connected devices? Here's the code I'm using:

HRESULT WiaCreateDeviceManager(IWiaDevMgr2 **ppWiaDevMgr)
{
    if(NULL == ppWiaDevMgr) return E_INVALIDARG;
    *ppWiaDevMgr = NULL;

    // Create an instance of the device manager
    HRESULT hr = CoCreateInstance(CLSID_WiaDevMgr2, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr2, (void**)ppWiaDevMgr);
    return hr;
}

HRESULT WiaEnumerateDevices(IWiaDevMgr2 *pWiaDevMgr)
{
    if(NULL == pWiaDevMgr)
    {
        return E_INVALIDARG;
    }

    // Get a device enumerator interface
    IEnumWIA_DEV_INFO *pWiaEnumDevInfo = NULL;
    HRESULT hr = pWiaDevMgr->EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo);
    assert(hr == S_OK);

    if(SUCCEEDED(hr))
    {
        ULONG count(911);
        HRESULT res = pWiaEnumDevInfo->GetCount(&count);
        if(res == S_OK) printf("EnumDeviceInfo: count = %lu\n", count); // count is always zero
        else printf("IEnumWIA_DEV_INFO::GetCount() failed!\n");

        // Loop until you get an error or pWiaEnumDevInfo->Next returns
        // S_FALSE to signal the end of the list.
        while(S_OK == hr)
        {
            // Get the next device's property storage interface pointer
            IWiaPropertyStorage *pWiaPropertyStorage = NULL;
            hr = pWiaEnumDevInfo->Next(1, &pWiaPropertyStorage, NULL);

            // pWiaEnumDevInfo->Next will return S_FALSE when the list is
            // exhausted, so check for S_OK before using the returned
            // value.
            if(hr == S_OK)
            {
                // Do something with the device's IWiaPropertyStorage*
                WiaReadProperties(pWiaPropertyStorage); // this line is never reached
                // Release the device's IWiaPropertyStorage*
                pWiaPropertyStorage->Release();
                pWiaPropertyStorage = NULL;
            }
        }

        // If the result of the enumeration is S_FALSE (which
        // is normal), change it to S_OK.
        if(S_FALSE == hr) hr = S_OK;

        // Release the enumerator
        pWiaEnumDevInfo->Release();
        pWiaEnumDevInfo = NULL;
    }

    return hr;
}

int main()
{
    ...
    IWiaDevMgr2 *wiamgr;
    WiaCreateDeviceManager(&wiamgr);
    HRESULT res = WiaEnumerateDevices(wiamgr); // res is always S_OK, but no device is detected
    ...
}
1
Well, your cameras just don't support WIA. Nothing unusual, they typically emulate a disk drive, making it easy to copy photos off the camera with Explorer. All that most users ever want to do. You'll have to put the camera in PTP mode, some background is here. Superuser.com is the best place to ask questions about that.Hans Passant
Hans, thank you for the reply. As far as I can tell, the cameras definitely support WIA. First of all, they do not show up in the file system like you're suggesting (my file manager can't see them). And second, the WIA-related PowerShell commands that the article you linked talks about are working fine.greentea101

1 Answers

2
votes

Apparently, WIA does not support camera devices on Windows Vista and later. I've only seen this implied or mentioned in passing twice in the WIA documentation, the last time being on this page. I can't believe this is happening, after I've spent so much time researching WIA. Apparently, I'm supposed to be using WPD for cameras, not WIA.

Edit: That being said, I'm still not sure what's going on. If I can't use WIA programmatically on Win 8.1, then why do these PowerShell commands work?

$WIAdialog = New-Object -ComObject "WIA.CommonDialog"
$Device    = $WIAdialog.ShowSelectDevice()
$i=$WIAdialog.ShowAcquireImage()
$i.SaveFile("$pwd\test.$($i.fileExtension)")

Is it that only the API doesn't work for cameras, while the Scripting Model does?