【问题标题】:CoCreateInstance for EnvDTE without an AddRef()?没有 AddRef() 的 EnvDTE 的 CoCreateInstance?
【发布时间】:2010-10-27 05:41:39
【问题描述】:

这与another question that I've asked 有点相关,我已经很清楚了。最后一块拼图是使用 CoCreateInstance() 而不是 GetActiveObject()。我不想使用现有的 EnvDTE 实例,所以我调用 CoCreateInstance,它会正确触发 VisualStudio 的新实例。 CoCreateInstance() 调用 AddRef() 并将输出指针存储在 CComPtr 中,该 CComPtr 在销毁时正确调用 Release。当这个 Release() 发生时,你瞧,VS 的实例就关闭了!当然会,因为引用计数为零。我想要做的是让新进程拥有最后一个实例,因此当用户使用关闭 (X) 按钮关闭 VS 时,它将破坏 COM 对象。

我尝试了一些事情: 1. 在我的 CComPtr 上调用 Detach(),让对象继续存在。当然可以,但是,使用关闭按钮关闭 VS 并不会真正终止进程(它仍在任务管理器列表中运行)。 2. 启动一个单独的VS进程,然后使用ROT找到新的实例。这很难看,因为在尝试查找 COM 对象的新实例之前,我必须等待应用程序启动的不确定时间。 3.使用全局或静态CComPtr,并在我的应用关闭时手动销毁对象。我宁愿不这样做。

【问题讨论】:

    标签: visual-studio com atl


    【解决方案1】:

    所以,对于使用 CoCreateInstance 创建 VisualStudio.DTE 对象的特定情况,我已经弄清楚了这一点。返回的 DTE 对象有一个 UserControl 属性,可以设置为 TRUE。当您将此设置为 TRUE 时,保存 DTE 对象的 CComPtr 的 Release() 不会破坏实例:

    #define RETURN_ON_FAIL( expression ) \
    result = ( expression );    \
    if ( FAILED( result ) )     \
        return false;           \
    else // To prevent danging else condition
    
    HRESULT result;
    CLSID clsid;
    CComPtr<IUnknown> punk = NULL;
    
    CComPtr<EnvDTE::_DTE> dte = NULL;
    RETURN_ON_FAIL( ::CLSIDFromProgID(L"VisualStudio.DTE", &clsid) );
    RETURN_ON_FAIL( ::CoCreateInstance( clsid, NULL, CLSCTX_LOCAL_SERVER, EnvDTE::IID__DTE, (LPVOID*)&punk ) );
    dte = punk;
    dte->put_UserControl( TRUE );
    

    【讨论】:

      【解决方案2】:

      看看WindowClosing Event。您可以订阅该事件,并在触发事件时调用 Release()。这将要求您确定要订阅哪些窗口事件。

      【讨论】:

        猜你喜欢
        • 2010-10-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 1970-01-01
        • 2010-12-08
        相关资源
        最近更新 更多