0

我正在浏览一个代码,它有一个具有 COM 服务器的 exe(在 ATL 中实现的 COM 类)。它有一个定义了所有接口的 .idl 文件。现在注册 COM 服务器后,我浏览了注册表项,我可以找到以下内容。每个接口都有一个带有其 IID 并具有 ProxyStubClsid32 的条目。有一个由我提到的 COM 服务器实现的接口,它在键字段中具有 IID = ProxyStubClsid32 的值,并且每个其他接口接口条目在其 ProxyStubClsid32 字段中具有相同的 IID 条目。为什么会这样??

接下来,当我尝试向 exe 添加一个新接口和实现该接口的新 COM 组件并进行注册时,我可以在注册表中观察到现在这个新接口的 IID 条目及其 ProxyStubClsid32 是相同的。并且新添加的 IID 现在存在于所有其他接口的 ProxyStubClsid32 中。

什么进入 ProxyStubClsid32,这是如何决定的?

即使在添加我的新接口之后,我也希望以前的 IID 出现在 ProxyStubClsid32 中。我怎样才能做到这一点 ??

explorer.exe 也会缓存此注册表项,因为我正在实现加载组件的 shell 扩展,我认为它指的是旧条目,因此在该 exe 上查询新接口不起作用。一旦我重新启动 explorer.exe 一切正常。

任何人都可以对此发表评论。

对此的回答似乎对我的问题有一些提示:Registry keys for out-of-process COM server

提前致谢。

4

1 回答 1

0

ProxyStubClsid32 中的内容实际上是 MIDL 用于编组的接口。使用它是因为您的接口继承自 IDispatch 并且是必需的,因此编译器负责编组(作为 OOP 服务器,您需要编组)。

对于我们的团队,我们在某些机器上注册服务器时遇到了一些问题(/RegServer 还不够),但是使用带有此代码的小 exe 解决了所有注册问题(因此您可能遇到的 E_NOINTERFACE 问题),只需调用它每次构建或安装后:

// Register the server
            String^ l_TLB = l_Path + "\\MyServer.tlb";
            IntPtr  l_TLBP = System::Runtime::InteropServices::Marshal::StringToBSTR(l_TLB);
            ITypeLib *pTypeLib;
            HRESULT hr;
            hr = LoadTypeLibEx(static_cast<LPCOLESTR>(l_TLBP.ToPointer()), REGKIND_REGISTER, &pTypeLib);
            if(SUCCEEDED(hr))
                pTypeLib->Release();
于 2013-09-16T06:39:24.237 回答