Search code examples
wpfdllc++-clidirectshow

Directshow Device Enumerator does not work in C++ CLI


I have the following C++ CLI code. It is placed in a function in a DLL which is called from a WPF application. The code has been taken from a working C++ application but does not work when in my C++ CLI DLL. The function CreateClassEnumerator returns error code 1.

Since the code is copied from a working C++ application which does successfully enumerate the video devices, I suspect that there is something a bit complicated going wrong (I am new to C++ CLI and DirectShow).

Google is throwing up a blank on this.

I was hoping for pointers as to what I can try or maybe I am misunderstanding something basic.

HRESULT status = S_OK;
System::Collections::Generic::List<System::String^>^ sourcesList = gcnew System::Collections::Generic::List<System::String^>();


ICreateDevEnum *pSystemDeviceEnumerator = nullptr;
status = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)(&pSystemDeviceEnumerator));

if (FAILED(status))
{
    return nullptr;
}

// create Class Enumerator that lists alls video input devices among the system devices
IEnumMoniker *pVideoInputDeviceEnumerator = nullptr;
status = pSystemDeviceEnumerator->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pVideoInputDeviceEnumerator, 0); // **** This function call fails ****

// release the System Device Enumerator which is not needed anymore
pSystemDeviceEnumerator->Release();
pSystemDeviceEnumerator = nullptr;

if (status != S_OK)
{
    return nullptr;
}

Solution

  • What "1" means

    "1" is equal to S_FALSE.

    The category specified by clsidDeviceClass does not exist or is empty.

    According to that the category is empty....so you don't have any video input devices.

    What might be happening is you are running your working C++ program example as 32bit, so it's trying to enumerate 32bit installed "filter" devices....and when you are in .NET you are using "Any CPU" as your target platform....and then it gets run as 64bit...so enumerating 64bit "filter" devices - try and use the same environment.

    In DirectShow, you use DirectShow codec/filters to access things (they are DLLs...but use the .AX file extension). There are 32bit and 64bit flavours of these. A 32bit app using DirectShow can only use 32bit filters/codecs...a 64bit app only 64bit filters.

    If your Windows version is a 64bit edition, then you will have just a 64bit driver installed to support the device...however, you should have both a 32bit and 64bit DirectShow filter installed to enable applications to access it via the DirectShow API (from either 32bit or 64bit apps).

    Post more code if you can, showing if you are calling this from a new thread, OS version, are you targeting x86 or x64 in your .NET app, etc.

    Thorlabs 32bit Filter Driver

    Thorlabs supply a 64bit driver for your OS which you have installed...and they also install and "register" another thing -> the 64bit directshow filter driver for you. But...from what you are saying (and is confirmed in the manual)...they don't register the 32bit filter driver as well (when they could have)....you have to do yourself.

    Refering to this manual for the DCC1545M (it's the closest I could find to your DCC1445M)...on page 16:

    Note: 64 bit operating systems

    If you want to use cameras in both 32 and 64 bit operating systems, you also have to manually register the cameras in the 32 bit subsystem. For this, use the 32 bit version of the DirectShow device manager. You can find the 32 bit DirectShow device manager in the Windows start menu.

    Registering a camera using the command line

    Registration can also be done using the command line or a batch file. To do this, you must first assign each camera a unique ID (identification number - see above). Next, call up the regsvr32.exe system program with the following parameters:

    regsvr32.exe <Path> /s /n /i:

    where is the path of the uc480Capture.ax file (usually C:\Windows\System32\uc480Capture.ax) and <No> is the number of cameras to be registered. If the number entered for <No> is less than the number of cameras that are currently registered, the cameras above and beyond this number are un-registered.

    So in a DOS prompt which has Administration Rights you need to run something like this:

    regsvr32.exe C:\Windows\System32\uc480Capture.ax /n /i:1
    

    The .AX file is the "Filter Driver". This might be named differently for different models of the camera, or it might use a common one between models...refer to your manual. Or alternatively, look for an .AX file with a similar looking name.

    However, I am not sure the above instructions are quite right...as the "system32" directory is meant to be for 64bit drivers and files.

    Assuming that the 64bit driver is the one in that location (and we want to register the 32bit one)...guessing, it means, the 32bit driver might be given a slightly different name e.g. say a "32" suffix on the end....or it is actually located in the "SysWOW64" windows folder.

    64bit Installation Log

    Looking at the installation log, after installing the 64bit "device" driver (the .sys files) I believe it's only ever trying to install a 32bit "directshow" filter driver (.ax)...thus only supports 32bit app usage.

    MSI (s) (9C:60) [05:55:02:510]: Executing op: ComponentRegister(ComponentId={289185DE-A478-4697-9E1C-5A20275B6C15},KeyPath=C:\Program Files\Thorlabs\Scientific Imaging\DCx Camera Support\USB Driver Package\uc480_64.sys,State=3,,Disk=1,SharedDllRefCount=0,BinaryType=1)
    1: {75E60A82-CF59-4C6A-81DD-621D0B76E94A} 2: {289185DE-A478-4697-9E1C-5A20275B6C15} 3: C:\Program Files\Thorlabs\Scientific Imaging\DCx Camera Support\USB Driver Package\uc480_64.sys
    etc... 
    ....
    MSI (s) (9C:60) [05:55:05:361]: File: C:\Windows\SysWOW64\uc480capture.ax;  To be installed;    Won't patch;    No existing file
    MSI (s) (9C:60) [05:55:05:361]: Source for file 'uc480capture.ax' is compressed
    InstallFiles: File: uc480capture.ax,  Directory: C:\Windows\SysWOW64\,  Size: 926720
    MSI (s) (9C:60) [05:55:21:083]: Executing op: ShortcutCreate(Name=DIRECT~1|DirectShow Device Manager,,,FileName=C:\Windows\SysWOW64\regsvr32.exe,Arguments=uc480capture.ax,,Icon=NewShortcut5_870BD7081A184F6E98DECF312BEC17F5.exe,IconIndex=0,,ShowCmd=1,,,,,)
    CreateShortcuts: Shortcut: DIRECT~1|DirectShow Device Manager