如何识别Microsoft COM-Server的客户端是在进程外还是在进程内?

时间:2015-10-20 15:10:09

标签: com interop com-interop com-server

我对Microsoft COM技术并不熟悉。简而言之,我在可执行文件foo.exe中实现了Microsoft Out-of-process COM Server。环境是C ++和Microsoft基础类框架(MFC)。

有一个客户端bar.exe,它使用foo.exe中的功能而不是Microsoft COM技术。在foo.exe中,涉及一些动态链接库,它还使用COM服务器foo.exe提供的功能(例如fooBar.dll)。

到目前为止一切顺利。我正在寻找一种方法来确定COM服务器foo.exe的客户端是否在其他进程中,或者甚至在与foo.exe相同的进程中,例如上面示例中的fooBar.dll。有谁知道这样的方式?

修改 换句话说:显然COM服务器foo.exe可以充当进程内或进程外的COM服务器。添加Hans Passant的评论和Joe Willcoxson的答案,他建议通过GetModuleHandle来解决调用DLL,以确定COM服务器当前是否作为进程内服务器,以防我得到句柄如果我没有得到作为进程外服务器的句柄。因此,当COM服务器知道在同一进程中使用来自该服务器的功能的众所周知的DLL时,我们可以说COM服务器此时作为进程内服务器而在其他情况下作为外部服务器。 -process Server。我是否误解了某些事情或者这些考虑是否正确?

我目前的调查没有提及,所以我希望社区中有一位知道手推车如何运行的Microsoft COM专家。

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我不确定一旦你有一个COM指针你会怎么做。但是,有一种方法可以在创建对象时使用。

CoCreateInstance()函数带有标记CLSCTX_INPROC_SERVER, CLSCTX_INPROC_HANDLER, CLSCTX_LOCAL_SERVER, CLSCTX_REMOTE_SERVER

当你使用ATL这样的东西时,通常默认的参数是组合标志,它只返回可用的东西。您可以单独尝试标记,看看是否使用特定标志创建了对象,而不是这样做。

我应该补充说,如果对象实际上是一个OLE对象/服务器,那就有一种方法。如果是这种情况,那么您可以查询IViewObject。如果它正在进行中,它就不会拥有该界面。如果它不在进程中,那么它将具有接口。

另一件事,如果对象实现了IRunnableObject并且你没有做任何事情来专门将它置于运行状态,那么进程内对象很可能处于运行状态,而进程外对象将不会在运行状态。

一个非常简单的黑客可能是使用DLL的名称调用GetModuleHandle()。如果它返回一个句柄,那么它就在进程中。它不是通用解决方案,它要求您事先知道DLL的名称。

答案 1 :(得分:0)

在COM服务器foo.exe中,您可以执行以下操作。

CTheApp::InitInstance()
{
    [...]
    bool runAsOutOfProcessServer = false;
    CCommandLineInfo commandInfo;
    ParseCommandLine(commandInfo);
    if(commandInfo.m_bRunEmbedded || commandInfo.m_bRunAutomated)
    { 
           runAsOutOfProcessServer = true;
    }
    [...]

    if(runAsOUtOfProcessServer)
       AfxMessageBox("Out of Process Invocation");
}

很明显CCommandLineInfo中有两个成员表示该进程是作为OLE自动化服务器启动的,或者是为了编辑嵌入式OLE项而启动的。使用ParseCommandLine,您可以通过引用本地变量commandInfo来获取调用信息。然后,您可以检查是否设置了成员m_bRunEmbeddedm_bRunAutomated以确定foo.exe中的COM服务器是否已启动。然后,只有当局部变量runAsOutOfProcessServer为真时,您才能弹出消息框。

相关问题