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

如何确定Microsoft COM服务器的客户端是否在进程外或进程内?,com,interop,com-interop,com-server,Com,Interop,Com Interop,Com Server,我不太熟悉微软的COM技术。简而言之,我在可执行文件foo.exe中实现了一个。环境是C++和微软基础类框架(MFC)。p> 有一个客户端bar.exe,它通过Microsoft COM技术使用foo.exe中的功能。在foo.exe中有一些动态链接库,它们还使用COM服务器foo.exe提供的功能(例如fooBar.dll) 到目前为止还不错。我正在寻找一种方法来确定COM服务器foo.exe的客户端是否位于其他进程中,或者甚至与foo.exe位于同一进程中,例如上面示例中的fooBar.dl

我不太熟悉微软的COM技术。简而言之,我在可执行文件
foo.exe
中实现了一个。环境是C++和微软基础类框架(MFC)。p> 有一个客户端
bar.exe
,它通过Microsoft COM技术使用foo.exe中的功能。在foo.exe中有一些动态链接库,它们还使用COM服务器foo.exe提供的功能(例如
fooBar.dll

到目前为止还不错。我正在寻找一种方法来确定COM服务器foo.exe的客户端是否位于其他进程中,或者甚至与foo.exe位于同一进程中,例如上面示例中的fooBar.dll。有人知道这种方法吗

编辑: 换句话说:显然,COM服务器
foo.exe
可以充当进程内或进程外的COM服务器。加上Hans Passant的评论和Joe Willcoxson的回答,Joe Willcoxson建议通过
GetModuleHandle
处理调用DLL,以确定COM服务器当前是否作为进程内服务器,以防在我获得句柄的情况下,以及在我没有获得进程外服务器的句柄的情况下。因此,当COM服务器知道在同一进程中使用该服务器功能的著名DLL时,我们可以说COM服务器此时充当进程内服务器,而在另一种情况下充当进程外服务器。我是否误解了什么,或者这些考虑是否正确

我的调查目前还没有被提及,所以我希望社区中有一位微软COM专家知道手推车是如何运转的


非常感谢你的帮助

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

CoCreateInstance()
函数采用标志
CLSCTX\u INPROC\u服务器、CLSCTX\u INPROC\u处理程序、CLSCTX\u本地\u服务器、CLSCTX\u远程\u服务器

通常,当您使用类似ATL的东西时,默认参数是组合标志,它只返回可用的任何内容。不必这样做,您可以单独尝试这些标志,并查看是否使用特定标志创建对象

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

还有一件事,如果对象实现了IRunnableObject,而您没有做任何事情专门将其置于运行状态,那么进程内对象很可能处于运行状态,而进程外对象将不处于运行状态


一个非常简单的方法是使用DLL的名称调用
GetModuleHandle()
。如果它返回一个句柄,那么它是进程中的。这不是一个通用的解决方案,它要求您事先知道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");
}

显然,其中有两个成员指示进程作为OLE Automation Server启动,或启动以编辑嵌入的OLE项。通过引用局部变量
commandInfo
,您可以通过调用获得信息。然后,您可以检查是否设置了成员
mu-bRunEmbedded
mu-bRunAutomated
,以确定
foo.exe
中的COM服务器是否已启动。最后,只有当局部变量
runAsOutOfProcessServer
为真时,您才能弹出消息框。

拥有有效的接口指针,您不必担心到底是谁实现了它,尤其是在进程外服务器的情况下,您不直接与服务器对话,而是与代理对话。也就是说,没有标准的方法,但您可以查询一些已知不能跨进程边界屏蔽的接口,如果您得到了指针,您就知道服务器在进程中。这个问题毫无意义,进程内/进程外的术语只适用于服务器。客户端代码总是存在于它自己的进程中。你是说服务器(而不是客户端)加载了一个DLL,然后在同一台服务器上调用方法?在任何情况下,你为什么关心谁在调用这个方法?您试图解决的实际问题是什么?@Hans Passant:我已经具体化了这个问题:我仍在寻找一种方法来确定COM服务器foo.exe的客户端是否处于其他进程中,或者甚至与foo.exe处于同一进程中,例如上面示例中的fooBar.dll。@Igor Tandetnik:是的,服务器加载了一个dll,然后在同一服务器上翻转并调用方法。我试图解决的问题是,当客户端在另一个进程中运行时,忽略弹出的消息框。如果客户端与foo.exe在同一进程中运行,我希望允许弹出消息框。谢谢您的回答。你给我带来了我附加在问题后面的进一步考虑。请参见编辑部分。