Directshow 设备枚举器在 C++ CLI 中不起作用

Directshow Device Enumerator does not work in C++ CLI

我有以下 C++ CLI 代码。它位于从 WPF 应用程序调用的 DLL 中的函数中。代码取自可工作的 C++ 应用程序,但在我的 C++ CLI DLL 中不起作用。函数CreateClassEnumerator returns 错误码1.

由于代码是从成功枚举视频设备的工作 C++ 应用程序复制的,我怀疑出现了一些复杂的错误(我是 C++ CLI 和 DirectShow 的新手)。

Google 对此一片空白。

我希望得到关于我可以尝试什么的指示,或者我可能误解了一些基本的东西。

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;
}

“1”是什么意思

"1" 等于 S_FALSE.

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

根据该类别是空的....因此您没有任何视频输入设备。

可能发生的情况是您正在 运行将您的工作 C++ 程序示例设置为 32 位,因此它试图枚举已安装的 32 位 "filter" 设备....当您在 .NET 中时您正在使用 "Any CPU" 作为您的目标平台....然后它得到 运行 作为 64 位...因此枚举 64 位 "filter" 设备 - 尝试使用相同的环境。

在 DirectShow 中,您可以使用 DirectShow codec/filters 访问内容(它们是 DLL...但使用 .AX 文件扩展名)。其中有 32 位和 64 位版本。使用 DirectShow 的 32 位应用程序只能使用 32 位 filters/codecs...64 位应用程序只能使用 64 位过滤器。

如果您的 Windows 版本是 64 位版本,那么您将只安装一个 64 位驱动程序来支持该设备...但是,您应该同时安装 32 位和 64 位 DirectShow 过滤器以启用应用程序通过 DirectShow API(从 32 位或 64 位应用程序)访问它。

Post 如果可以,请提供更多代码,显示您是否从新线程调用它,OS 版本,您的 .NET 应用程序中的目标是 x86 还是 x64,等等。

Thorlabs 32 位过滤器驱动程序

Thorlabs 为您安装的 OS 提供 64 位驱动程序...他们还安装 "register" 另一件事 -> 为您提供 64 位 directshow 过滤器驱动程序。但是......根据你所说的(并在手册中确认)......他们也没有注册 32 位过滤器驱动程序(当他们可以注册时)......你必须自己做。

参考 DCC1545M 手册(这是我能找到的最接近您的 DCC1445M 的手册)...第 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.

因此,在具有管理权限的 DOS 提示符中,您需要 运行 像这样:

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

.AX 文件是 "Filter Driver"。对于不同型号的相机,这可能有不同的名称,或者它可能在不同型号之间使用通用的名称......请参阅您的手册。或者,查找名称相似的 .AX 文件。

但是,我不确定上面的说明是否正确...因为 "system32" 目录是为 64 位驱动程序和文件准备的。

假设 64 位驱动程序是那个位置的驱动程序(我们想注册 32 位驱动程序)...猜测,这意味着 32 位驱动程序可能会被赋予一个稍微不同的名称,例如在末尾说一个“32”后缀....或者它实际上位于 "SysWOW64" windows 文件夹中。

64 位安装日志

查看安装日志,在安装 64 位 "device" 驱动程序(.sys 文件)后,我相信它只会尝​​试安装 32 位 "directshow" 过滤驱动程序(.ax).. .thus 仅支持 32 位应用程序使用。

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