为什么COM忽略我的DllSurrogate条目?

时间:2009-12-10 11:09:45

标签: com

我知道this question,但我已经按照那里列出的步骤进行了操作,但我仍然感到难过。

我有一个类,注册如下(这是一个RGS文件):

HKCR
{
    NoRemove CLSID
    {
        ForceRemove {5CB1D770-BF72-4F3D-B4DA-85E0542126F4} = s 'ExamplePlugin Class'
        {
            val AppID = s '%APPID%'
            InprocServer32 = s '%MODULE%'
            {
                val ThreadingModel = s 'Free'
            }
        }
    }
}

我有一个AppID,注册如下:

HKCR
{
    NoRemove AppID
    {
        '%APPID%' = s 'ExamplePlugin'
        {
            val DllSurrogate = s ''
        }
        'ExamplePlugin.DLL'
        {
            val AppID = s '%APPID%'
        }
    }
}

我将CLSCTX_ALL传递给CComPtr<IPlugin>::CoCreateInstance

简而言之,据我所知,我已经关注the checklist

  1. 我的CLSID下指定了AppID值。我有一个相应的AppID密钥。
  2. 我在激活调用中包含了CLSCTX_LOCAL_SERVER。我的CLSID密钥没有任何LocalServer密钥。
  3. 我的CLSID密钥包含InprocServer32密钥。
  4. 我假设当核对表说“InprocServer32中指定的代理/存根DLL存在”时,它意味着“实现DLL”。它确实存在。我的代理/存根DLL在其他地方正确注册。
  5. 我的AppID键下有一个DllSurrogate值。
  6. 如果我在OLE / COM对象查看器中查看我的类,它看起来是正确的(“实现”选项卡已选中“使用代理进程”。)

    它仍然无效:我的DLL加载到与我的主机EXE相同的进程中。

    线索:如果我运行Process Monitor,我看不到它正在寻找CLSID\{...}\AppID值。如果我将CLSCTX_LOCAL_SERVER传递给CoCreateInstance,则会返回“class not registered”。

    我使用的是Windows 2008 x64,但我尝试使用为x86和x64编译的代码,结果相同。

    我错过了什么?

2 个答案:

答案 0 :(得分:3)

您必须将CLSCTX_LOCAL_SERVER指定给CoCreateInstance()以强制执行out-proc激活。这是DCOM的特性 - 如果您的组件被注册为进程内COM服务器并且您指定了一个CLSCTX_掩码,包括进程内激活的任何值,则组件在进程中被激活 - 不使用DCOM。

请注意,COM +提供了几乎相同的功能,但如果您创建“服务器应用程序”并在那里添加组件然后指定CLSCTX_ALL,组件将在COM +代理中实例化 - 将自动选择out-proc激活。

答案 1 :(得分:1)

事实证明,文档具有误导性。仅仅设置CLSCTX_LOCAL_SERVER是不够的。您还必须从对CoCreateInstance的调用中删除CLSCTX_INPROC值。如果不这样做,COM将始终使用进程内的东西,永远不会查询DllSurrogate。