为什么 CoCreateInstance returns REGDB_E_CLASSNOTREG 在某些 Windows 上?
Why CoCreateInstance returns REGDB_E_CLASSNOTREG on some Windows?
我想使用 DSound Audio Render in one of my application so I load it with CoCreateInstance。这是一个小片段:
#include <iostream>
#include <strmif.h>
#include <uuids.h>
int main()
{
std::cout << "Start" << std::endl;
HRESULT hr = CoInitialize(NULL);
printf("CoInitialize = 0x%x\n", hr);
IBaseFilter* ptr = NULL;
hr = CoCreateInstance(CLSID_DSoundRender, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&ptr);
printf("CoCreateInstance = 0x%x\n", hr);
ptr->Release();
CoUninitialize();
std::cout << "End" << std::endl;
std::cin.get();
}
问题是,在我用来开发我的应用程序的 Windows 上,它运行良好并且 hr
总是 0x0
(S_OK
) 但在 Windows,当调用 CoCreateInstance
时出现错误 0x0x80040154
(REGDB_E_CLASSNOTREG
)。
这是一个 32 位应用程序 运行 Windows 10 64 位(对于开发)和 Windows Server 2016 Datacenter 64 位(对于产品)。
我检查了注册表,相应的DLL(quartz.dll
)被正确注册了。事实上,我在 Windows:
上都得到了这些结果
PS C:\Users\pierre> Get-ChildItem -Path "Registry::HKCR\CLSID\{79376820-07D0-11CF-A24D-0020AFD79767}"
Hive: HKCR\CLSID\{79376820-07D0-11CF-A24D-0020AFD79767}
Name Property
---- --------
InprocServer32 (default) : C:\Windows\System32\quartz.dll
ThreadingModel : Both
PS C:\Users\pierre> Get-ChildItem -Path "Registry::HKCR\WOW6432Node\CLSID\{79376820-07D0-11CF-A24D-0020AFD79767}"
Hive: HKCR\WOW6432Node\CLSID\{79376820-07D0-11CF-A24D-0020AFD79767}
Name Property
---- --------
InprocServer32 (default) : C:\Windows\SysWOW64\quartz.dll
ThreadingModel : Both
PS C:\Users\pierre> dir C:\Windows\System32\quartz.dll
Répertoire : C:\Windows\System32
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 15/09/2018 09:29 1639424 quartz.dll
PS C:\Users\pierre> dir C:\Windows\SysWOW64\quartz.dll
Répertoire : C:\Windows\SysWOW64
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 15/09/2018 09:29 1470464 quartz.dll
我也用过procmon.exe
,每次调用看起来都是正确的。
我应该在我的客户端配置中更改什么才能使其正常工作?
MSDN explains "Remarks" 部分下此 DirectShow 过滤器应该如何参与 DirectShow 图形管道:
This filter acts as a wrapper for an audio device. To enumerate the audio devices available on the user's system, use the ICreateDevEnum interface with the audio renderer category (CLSID_AudioRendererCategory). For each audio device, the audio renderer category contains two filter instances. One of these corresponds to the DirectSound Renderer, and the other corresponds to the Audio Renderer (WaveOut) filter. The DirectSound instance has the friendly name "DirectSound: DeviceName," where DeviceName is the name of the device. The WaveOut instance has the friendly name DeviceName.
请注意,您通常不应该直接使用 CoCreateInstance
实例化过滤器,您正在做什么。这是有充分理由的:它是一个包装对象,它通常需要将其绑定到特定音频输出设备的初始化上下文。通过直接初始化,您隐式地指示它使用默认设备。
在没有音频输出设备的系统上,过滤器将看不到任何设备,并且可能会在早期实例化步骤中发出故障,从而导致 COM 错误。您会看到 COM 注册,但缺少硬件和早期故障会触发一般 COM 错误,而不是 API 特定错误。
一般来说,与 CoCreateInstance
.
相比,您仍然应该更喜欢使用 ICreateDevEnum
界面(如 MSDN 推荐的那样)
我想使用 DSound Audio Render in one of my application so I load it with CoCreateInstance。这是一个小片段:
#include <iostream>
#include <strmif.h>
#include <uuids.h>
int main()
{
std::cout << "Start" << std::endl;
HRESULT hr = CoInitialize(NULL);
printf("CoInitialize = 0x%x\n", hr);
IBaseFilter* ptr = NULL;
hr = CoCreateInstance(CLSID_DSoundRender, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&ptr);
printf("CoCreateInstance = 0x%x\n", hr);
ptr->Release();
CoUninitialize();
std::cout << "End" << std::endl;
std::cin.get();
}
问题是,在我用来开发我的应用程序的 Windows 上,它运行良好并且 hr
总是 0x0
(S_OK
) 但在 Windows,当调用 CoCreateInstance
时出现错误 0x0x80040154
(REGDB_E_CLASSNOTREG
)。
这是一个 32 位应用程序 运行 Windows 10 64 位(对于开发)和 Windows Server 2016 Datacenter 64 位(对于产品)。
我检查了注册表,相应的DLL(quartz.dll
)被正确注册了。事实上,我在 Windows:
PS C:\Users\pierre> Get-ChildItem -Path "Registry::HKCR\CLSID\{79376820-07D0-11CF-A24D-0020AFD79767}"
Hive: HKCR\CLSID\{79376820-07D0-11CF-A24D-0020AFD79767}
Name Property
---- --------
InprocServer32 (default) : C:\Windows\System32\quartz.dll
ThreadingModel : Both
PS C:\Users\pierre> Get-ChildItem -Path "Registry::HKCR\WOW6432Node\CLSID\{79376820-07D0-11CF-A24D-0020AFD79767}"
Hive: HKCR\WOW6432Node\CLSID\{79376820-07D0-11CF-A24D-0020AFD79767}
Name Property
---- --------
InprocServer32 (default) : C:\Windows\SysWOW64\quartz.dll
ThreadingModel : Both
PS C:\Users\pierre> dir C:\Windows\System32\quartz.dll
Répertoire : C:\Windows\System32
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 15/09/2018 09:29 1639424 quartz.dll
PS C:\Users\pierre> dir C:\Windows\SysWOW64\quartz.dll
Répertoire : C:\Windows\SysWOW64
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 15/09/2018 09:29 1470464 quartz.dll
我也用过procmon.exe
,每次调用看起来都是正确的。
我应该在我的客户端配置中更改什么才能使其正常工作?
MSDN explains "Remarks" 部分下此 DirectShow 过滤器应该如何参与 DirectShow 图形管道:
This filter acts as a wrapper for an audio device. To enumerate the audio devices available on the user's system, use the ICreateDevEnum interface with the audio renderer category (CLSID_AudioRendererCategory). For each audio device, the audio renderer category contains two filter instances. One of these corresponds to the DirectSound Renderer, and the other corresponds to the Audio Renderer (WaveOut) filter. The DirectSound instance has the friendly name "DirectSound: DeviceName," where DeviceName is the name of the device. The WaveOut instance has the friendly name DeviceName.
请注意,您通常不应该直接使用 CoCreateInstance
实例化过滤器,您正在做什么。这是有充分理由的:它是一个包装对象,它通常需要将其绑定到特定音频输出设备的初始化上下文。通过直接初始化,您隐式地指示它使用默认设备。
在没有音频输出设备的系统上,过滤器将看不到任何设备,并且可能会在早期实例化步骤中发出故障,从而导致 COM 错误。您会看到 COM 注册,但缺少硬件和早期故障会触发一般 COM 错误,而不是 API 特定错误。
一般来说,与 CoCreateInstance
.
ICreateDevEnum
界面(如 MSDN 推荐的那样)