为什么CoCreateInstance在某些Windows上返回REGDB_E_CLASSNOTREG?

问题描述 投票:1回答:1

我想在我的一个应用程序中使用DSound Audio Render,所以我用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总是0x0S_OK)但在我的客户端的Windows上,当调用0x0x80040154时,它会得到错误REGDB_E_CLASSNOTREGCoCreateInstance)。

它是一个32位应用程序,运行在Windows 10 64位(对于开发人员)和Windows Server 2016 Datacenter 64位(对于prod)。

我检查注册表和相应的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,每个电话看起来都是正确的。

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

c++ audio com directshow windows-server-2016
1个回答
2
投票

MSDN explains在“备注”部分下这个DirectShow过滤器应该如何参与DirectShow图形管道:

此过滤器充当音频设备的包装器。要枚举用户系统上可用的音频设备,请将ICreateDevEnum接口与音频渲染器类别(CLSID_AudioRendererCategory)一起使用。对于每个音频设备,音频渲染器类别包含两个过滤器实例。其中一个对应于DirectSound渲染器,另一个对应于音频渲染器(WaveOut)过滤器。 DirectSound实例具有友好名称“DirectSound:DeviceName”,其中DeviceName是设备的名称。 WaveOut实例具有友好名称DeviceName。

请注意,您通常不应该使用CoCreateInstance直接实例化过滤器,您正在做什么。这有一个很好的理由:它是一个包装对象,它通常需要它的初始化上下文,它将它绑定到特定的音频输出设备。通过直接初始化,您隐式指示它使用默认设备。

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

通常,您仍然应该更喜欢使用ICreateDevEnum接口(如MSDN推荐的那样)来使用CoCreateInstance

© www.soinside.com 2019 - 2024. All rights reserved.