如何确定 Microsoft COM 服务器的客户端是进程外还是进程内?

How do I identify if a client of a Microsoft COM-Server is out-of-process or within the process?

我对Microsoft COM 技术不是很熟悉。简而言之,我有一个在可执行文件 foo.exe 中实现的 Microsoft Out-of-process COM Server。环境是C++和Microsoft Foundation 类 Framework (MFC)。

有一个客户端 bar.exe,它通过 Microsoft COM 技术使用 foo.exe 中的功能。 foo.exe 中涉及一些动态 Link 库,它们也使用 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 服务器此时充当进程内服务器,而在其他情况下充当进程外服务器-进程服务器。我是否误解了什么或者这些考虑是否正确?

暂时我的调查就不提了,希望社区里有微软COM专家知道推车是怎么跑的。

非常感谢您的帮助!

我不确定如果您已经有了 COM 指针,您会怎么做。但是,创建对象时有一种方法。

CoCreateInstance() 函数采用标志 CLSCTX_INPROC_SERVER, CLSCTX_INPROC_HANDLER, CLSCTX_LOCAL_SERVER, CLSCTX_REMOTE_SERVER

通常,当您使用像 ATL 这样的东西时,默认参数是组合标志,它只是 returns 可用的任何东西。除了这样做,您还可以单独尝试这些标志,看看是否使用特定标志创建了对象。

我应该补充一点,如果对象实际上是一个 OLE object/server,那么有一种方法。如果是这种情况,那么您可以查询 IViewObject。如果它在进程中,它不会有那个界面。如果它在进程外,那么它将具有接口。

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

一个非常简单的 hack 可能是用 DLL 的名称调用 GetModuleHandle()。如果它 returns 一个句柄,那么它是进程中的。这不是一个通用的解决方案,它需要您事先知道 DLL 的名称。

在 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 which indicates that the process is started up as OLE Automation Server or started up to edit an embedded OLE item. With ParseCommandLine 中有两个成员,您通过引用局部变量 commandInfo 获得了调用信息。然后可以查看成员m_bRunEmbeddedm_bRunAutomated是否设置,判断foo.exe内的COM Server是否启动。然后最后只有当局部变量runAsOutOfProcessServer为真时你才能弹出你的消息框。