是否有可能有一个进程外COM服务器,其中每个对象实例使用单独的操作系统进程?

时间:2010-05-24 15:08:19

标签: c++ com winapi

我有一个遗留的C ++“解决方案引擎”,我已将其作为进程内COM对象包装,供仅需要单个“解决方案引擎”的客户端应用程序使用。

但是我现在有一个需要多个“解决方案引擎”的客户端应用程序。遗憾的是,底层遗留代码具有足够的全局数据,单例和线程恐怖,在给定可用资源的情况下,不可能同时在其中处理多个实例。

我希望是某种善良的灵魂可以告诉我一些COM魔术在哪里通过几个注册表设置的翻转,可以有一个单独的进程外COM服务器(单独的操作系统进程)请求的COM对象的每个实例。

我好运吗?

3 个答案:

答案 0 :(得分:8)

是的,这是可能的。关键是通过调用CoRegisterClassObject来注册您的coclass,并在flags参数中的值REGCLS_SINGLEUSE中注册OR。

如果您的项目是ATL 7.0+项目,您可以通过覆盖负责注册类对象的CAtlExeModuleT::PreMessageLoop()来执行此操作:

HRESULT CATLHacksModule::PreMessageLoop(int nShow)
{
    HRESULT hr = RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE);
    if (hr == S_OK)
    {
        if (m_bDelayShutdown && !StartMonitor())
        {
            hr = E_FAIL;
        }
    }
    else
    {
        m_bDelayShutdown = false;
    }
    return hr;
}

答案 1 :(得分:1)

您需要一个“主”coclass来锁定EXE实例,类似于“应用程序”界面。找到其工厂的CoRegisterClassObject()调用。并将REGCLS参数更改为REGCLS_SINGLEUSE。

一旦第一个客户端连接到它,它将自动取消注册类工厂。再次为该工厂调用CoCreateInstance()会启动服务器的新实例。我想。

答案 2 :(得分:-2)

我很确定这是不可能的。 COM out-of-proc服务器必须全局注册它提供的类对象(通过CoRegisterClassObject);此注册的一部分是GUID类。显然你不能两次注册相同的GUID。