C++ 跨会话激活。会话名字对象被忽略

C++ 跨会话激活。会话名字对象被忽略,c++,windows,com,C++,Windows,Com,我的windows pc上有两个帐户:\A1和\SYSTEM。我的测试项目由三个应用程序组成: Server.exe-退出proc com服务器。实现对象Q Service.exe-退出proc com服务。实现对象T Client.exe-客户端应用程序 我的工作流程如下所示: 我登录了\A1。我启动“Client.exe” 客户端创建对象“T”的实例 客户机调用一些方法,比如'T.ActivateQ',该方法实例化'Q' 我的目的是使Service.exe在帐户\A1中创建“Q”的实例,即使

我的windows pc上有两个帐户:\A1和\SYSTEM。我的测试项目由三个应用程序组成:

  • Server.exe-退出proc com服务器。实现对象Q
  • Service.exe-退出proc com服务。实现对象T
  • Client.exe-客户端应用程序
  • 我的工作流程如下所示:

  • 我登录了\A1。我启动“Client.exe”
  • 客户端创建对象“T”的实例
  • 客户机调用一些方法,比如'T.ActivateQ',该方法实例化'Q' 我的目的是使Service.exe在帐户\A1中创建“Q”的实例,即使Service.exe位于\SYSTEM帐户下

    正如文章中所述,Windows内置了进行这种激活的功能,称为“会话到会话激活”。它通过会话名字对象(“会话:!clsid:”)实现

    鉴于此,我已将“Server.exe”配置为通过dcomcnfg作为“交互式用户”运行。 然后我实现了函数“CoGetClassObjectInSession”:

    void CoGetClassObjectInSession(DWORD sessionId, Guid const& clsid, void *pvReserved, Guid const& riid, void **ppv)
    {
        ATL::CComQIPtr<IBindCtx> bindCtxInst;
        COMCHK(CreateBindCtx(NULL, &bindCtxInst));
    
        CComQIPtr<IMoniker> classMonikerInst;
        COMCHK(::CreateClassMoniker(clsid, &classMonikerInst));
    
        std::wstringstream ss;
        ss << L"Session:" << std::dec << sessionId;
    
        ULONG parsed;
        ATL::CComQIPtr<IMoniker> sessionMonikerInst;
        COMCHK(::MkParseDisplayNameEx(bindCtxInst, ss.str().c_str(), &parsed, &sessionMonikerInst));
    
        ATL::CComQIPtr<IMoniker> classObjectMoniker;
        COMCHK(sessionMonikerInst->ComposeWith(classMonikerInst, FALSE, &classObjectMoniker));
    
    
        ATL::CComPtr<IClassFactory> sessionFactoryInst;
        COMCHK(classObjectMoniker->BindToObject(bindCtxInst, NULL, riid, ppv));
    }
    
    Server.rgs文件:

    HKLM
    {
        NoRemove Software
        {
            NoRemove Classes
            {
                NoRemove AppID
                {
                    ForceRemove '%APPID%' = s 'Test Server'
                    {
                        val RunAs = s 'Interactive User'
                    }
                }
            }
        }
    }
    
    我做错什么了吗

    更新 我终于找到了解决办法。类“Q”的注册脚本缺少AppID字段:

    HKCR
    {
        NoRemove CLSID
        {
            ForceRemove {6FDE856C-F1B2-4466-8435-20F4AEF2C2E1} = s 'SMonClass Class'
            {
                ForceRemove Programmable
                LocalServer32 = s '%MODULE%'
                {
                    val ServerExecutable = s '%MODULE_RAW%'
                }
                TypeLib = s '{4FA39B0F-5B24-43C6-A5B1-11D8F34277B7}'
                Version = s '1.0'
    
                --> val AppID = s '%APPID%'** <-- This line
    
            }
        }
    }
    
    HKCR
    {
    NoRemove CLSID
    {
    ForceRemove{6FDE856C-F1B2-4466-8435-20F4AEF2C2E1}=s'SMonClass'
    {
    强制移除可编程
    LocalServer32=s“%MODULE%”
    {
    val ServerExecutable=s“%MODULE_RAW%”
    }
    TypeLib=s'{4FA39B0F-5B24-43C6-A5B1-11D8F34277B7}'
    版本=s“1.0”
    
    -->val AppID=s“%AppID%”***@VJovic,您可能会找到一个很好的解释。客户端实例化一个Q(它将自动处于正确的会话中)并将其传递给t会简单得多吗?@arx,不幸的是,客户端应该不知道此操作。此外,客户端的生存期可能比服务器的短。
    HKLM
    {
        NoRemove Software
        {
            NoRemove Classes
            {
                NoRemove AppID
                {
                    ForceRemove '%APPID%' = s 'Test Server'
                    {
                        val RunAs = s 'Interactive User'
                    }
                }
            }
        }
    }
    
    HKCR
    {
        NoRemove CLSID
        {
            ForceRemove {6FDE856C-F1B2-4466-8435-20F4AEF2C2E1} = s 'SMonClass Class'
            {
                ForceRemove Programmable
                LocalServer32 = s '%MODULE%'
                {
                    val ServerExecutable = s '%MODULE_RAW%'
                }
                TypeLib = s '{4FA39B0F-5B24-43C6-A5B1-11D8F34277B7}'
                Version = s '1.0'
    
                --> val AppID = s '%APPID%'** <-- This line
    
            }
        }
    }