进程外COM服务器的注册表项

进程外COM服务器的注册表项,com,out-of-process,Com,Out Of Process,我正在实现我的第一个进程外COM服务器(就此而言,我的第一个COM服务器)。我按照以下步骤编写了一个IDL文件,为代理/存根DLL生成代码,编译DLL并注册它 当我检查注册表项时,我 名为HKEY\u CLASSES\u ROOT/Interface/的键,其值为(比如)IMyApp和 名为HKEY\U CLASSES\U ROOT/Interface//ProxyStubClsid32的键,其值为,即与键名中的值相同 我不明白第二个键的值如何与键名中的值相同,因为我目前的理解是 在HKE

我正在实现我的第一个进程外COM服务器(就此而言,我的第一个COM服务器)。我按照以下步骤编写了一个IDL文件,为代理/存根DLL生成代码,编译DLL并注册它

当我检查注册表项时,我

  • 名为
    HKEY\u CLASSES\u ROOT/Interface/
    的键,其值为(比如)
    IMyApp
  • 名为
    HKEY\U CLASSES\U ROOT/Interface//ProxyStubClsid32
    的键,其值为
    ,即与键名中的值相同
我不明白第二个键的值如何与键名中的值相同,因为我目前的理解是

  • HKEY\u CLASSES\u ROOT/Interface/
    中,GUID是一个接口ID
  • ProxyStubClsid32
    不是接口ID,而是引用实现上述接口的组件的ID
  • HKEY\u CLASSES\u ROOT/CLSID//InprocServer32
    (其中GUID是上述ID)的值指向代理DLL
那么,如果一个是接口ID,另一个是类ID,
HKEY\u CLASSES\u ROOT/Interface//ProxyStubClsid32
的值如何保持相同的值GUID


编辑:我仍然希望得到这个问题的答案。简而言之:既然组件和接口是两件不同的事情,那么如何将相同的ID用于两者呢?

您对COM中使用GUID的基本理解是正确的。首先值得注意的是,具有相同guid的接口和类不是问题。它们位于不同的注册表项中,HKCR\Interface与HKCR\CLSID,在COM中,无论您是在查找IID还是CLSID,总是很清楚

第二个是您编写的IDL。注意,这里没有指定代理的CLSID的位置,只有代理和存根支持的IID可以在那里声明

接下来,您需要通过自动生成代理/存根的方式进行白鹅追逐。Windows SDK的核心头文件是RpcProxy.h,请在文本编辑器中打开它查看。宏汤很重,但它确实有一些像样的评论来描述正在发生的事情。重要的RPC帮助程序函数是NdrDllRegisterProxy(),它注册代理并在使用Regsvr32.exe时调用。其第3个参数指定代理的CLSID。我将让您阅读并引用.h文件中的重要部分:

编译器开关:

-DPROXY_CLSID=clsid
    Specifies a class ID to be used by the proxy DLL.
您可以使用“项目+属性”、“C/C++”、“预处理器”、“预处理器定义”设置来指定此项。请注意,您的项目不会指定它

在汤中追逐,然后让你进入这一步:

// if the user specified an override for the class id, it is
// PROXY_CLSID at this point

#ifndef PROXY_CLSID
#define GET_DLL_CLSID   \
    ( aProxyFileList[0]->pStubVtblList[0] != 0 ? \
    aProxyFileList[0]->pStubVtblList[0]->header.piid : 0)
#else  //PROXY_CLSID
#define GET_DLL_CLSID   &PROXY_CLSID
#endif //PROXY_CLSID
换句话说,如果您自己没有指定CLSID(您没有),那么它将使用存根表中的第一个IID


这使得ProxyStubClsid32 guid与第一个接口的IID相同。特性,而不是bug。

您对COM中使用GUI的基本理解是正确的。首先值得注意的是,具有相同guid的接口和类不是问题。它们位于不同的注册表项中,HKCR\Interface与HKCR\CLSID,在COM中,无论您是在查找IID还是CLSID,总是很清楚

第二个是您编写的IDL。注意,这里没有指定代理的CLSID的位置,只有代理和存根支持的IID可以在那里声明

接下来,您需要通过自动生成代理/存根的方式进行白鹅追逐。Windows SDK的核心头文件是RpcProxy.h,请在文本编辑器中打开它查看。宏汤很重,但它确实有一些像样的评论来描述正在发生的事情。重要的RPC帮助程序函数是NdrDllRegisterProxy(),它注册代理并在使用Regsvr32.exe时调用。其第3个参数指定代理的CLSID。我将让您阅读并引用.h文件中的重要部分:

编译器开关:

-DPROXY_CLSID=clsid
    Specifies a class ID to be used by the proxy DLL.
您可以使用“项目+属性”、“C/C++”、“预处理器”、“预处理器定义”设置来指定此项。请注意,您的项目不会指定它

在汤中追逐,然后让你进入这一步:

// if the user specified an override for the class id, it is
// PROXY_CLSID at this point

#ifndef PROXY_CLSID
#define GET_DLL_CLSID   \
    ( aProxyFileList[0]->pStubVtblList[0] != 0 ? \
    aProxyFileList[0]->pStubVtblList[0]->header.piid : 0)
#else  //PROXY_CLSID
#define GET_DLL_CLSID   &PROXY_CLSID
#endif //PROXY_CLSID
换句话说,如果您自己没有指定CLSID(您没有),那么它将使用存根表中的第一个IID


这使得ProxyStubClsid32 guid与第一个接口的IID相同。功能,而不是bug。

初学者困惑案例(tm)。通过调用
regsrv32
注册的类不是具有myCLSID的类。它是专门为代理/存根DLL生成的(友好名称PSFactory也表示这一点)。正如罗曼·R.所怀疑的,有两个阶级,我以为只有一个。当使用
/Embedding
开关调用我自己的CLSID时,EXE服务器会注册它。

初学者困惑案例(tm)。通过调用
regsrv32
注册的类不是具有myCLSID的类。它是专门为代理/存根DLL生成的(友好名称PSFactory也表示这一点)。正如罗曼·R.所怀疑的,有两个阶级,我以为只有一个。我自己的CLSID在使用
/Embedding
开关调用时由EXE服务器注册。

据我所知,所有代理/存根混乱现在都由MIDL管理(继承自IDispatch而非IUnknown,您可能已经这样做了,因为您有ProxyStubClsid32注册表项)

唯一需要做的就是正确注册服务器(只是构建它或doing/RegServer没有为我们以及其他许多人正确注册它),要做到这一点,只需要调用LoadTypeLibEx(在构建服务器或安装它之后)

所以只要用这个c创建一个小的exe