为什么CoCreateInstance在某些Windows上返回REGDB_E_CLASSNOTREG? [英] Why CoCreateInstance returns REGDB_E_CLASSNOTREG on some Windows?

查看:370
本文介绍了为什么CoCreateInstance在某些Windows上返回REGDB_E_CLASSNOTREG?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 DSound音频渲染在我的一个应用程序中,因此我使用

I want to use DSound Audio Render in one of my application so I load it with CoCreateInstance. Here is a little snippet:

#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上,它显示了错误0x0x80040154( REGDB_E_CLASSNOTREG)时调用CoCreateInstance.

The problem is, on the Windows I use to develop my application, it works well and hr is always 0x0 (S_OK) but on the Windows of my client, it gets an error 0x0x80040154 (REGDB_E_CLASSNOTREG) when CoCreateInstance is called.

这是一个32位应用程序,在Windows 10 64位(用于开发人员)和Windows Server 2016 Datacenter 64位(用于产品)上运行.

It's a 32 bits application running on Windows 10 64 bits (for the dev) and on Windows Server 2016 Datacenter 64 bits (for the prod).

我检查注册表,并且正确注册了相应的DLL(quartz.dll).确实,我在两个Windows上都得到了这些结果:

I check the registry and the corresponding DLL (quartz.dll) is correctly registered. Indeed, I get those results on both 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 ,并且每个调用看起来都是正确的

I also used procmon.exe and every calls look correct.

我应该如何更改客户端的配置以使其正常工作?

What should I change in the configuration of my client to make it work?

推荐答案

MSDN在备注"部分解释,该DirectShow过滤器应如何参与DirectShow图形管道:

MSDN explains under "Remarks" section how this DirectShow filter is supposed to participate in DirectShow graph pipelines:

此过滤器用作音频设备的包装器.要枚举用户系统上可用的音频设备,请使用ICreateDevEnum接口和音频渲染器类别(CLSID_AudioRendererCategory).对于每个音频设备,音频渲染器类别包含两个过滤器实例.其中一个对应于DirectSound Renderer,另一个对应于Audio Renderer(WaveOut)过滤器. DirectSound实例的友好名称为"DirectSound:DeviceName",其中DeviceName是设备的名称. WaveOut实例的友好名称为DeviceName.

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实例化过滤器.这样做有一个很好的理由:它是一个包装对象,通常需要将其绑定到特定的音频输出设备的初始化上下文.通过直接初始化,您隐式指示其使用默认设备.

Note that you are not generally supposed to instaniate the filter directly using CoCreateInstance, what you are doing. There is a good reason for this: it is a wrapping object and it normally needs its initialization context whcih binds it to specific audio output device. By doing direct initialization you implicitly instructing it to use default device.

在没有音频输出设备的系统上,过滤器将看不到任何设备,并且可能会在早期实例化步骤中发出故障,从而导致COM错误.您会看到COM注册,但是没有硬件和早期故障会触发一般的COM错误,而不是特定于API.

On systems without audio output devices the filter would see no devices and might issue a failure at early instantiation step, resulting in COM error. You would see the COM registration but absence of hardware and early failure would trigger a generic COM error rather than API specific.

通常,与CoCreateInstance相比,您仍应首选使用ICreateDevEnum界面(如MSDN建议).

In general, you should still prefer use of ICreateDevEnum interface (as MSDN recommends) to CoCreateInstance.

这篇关于为什么CoCreateInstance在某些Windows上返回REGDB_E_CLASSNOTREG?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆