没有AddRef()的EnvDTE的CoCreateInstance?

时间:2009-05-19 05:37:23

标签: visual-studio com atl

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

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

2 个答案:

答案 0 :(得分: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 );

答案 1 :(得分:0)

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