2009-05-19 47 views
1

这与another question that I've asked有点相关,我几乎想通了。最后一块难题是使用CoCreateInstance()而不是GetActiveObject()。我不想使用EnvDTE的现有实例,因此我调用了CoCreateInstance,它可以正确触发VisualStudio的新实例。 CoCreateInstance()调用AddRef(),并将输出指针存储在一个CComPtr中,该指针正确调用销毁上的Release。当这个版本()发生的时候,看看VS的实例关闭!当然这是因为refcount为零。我想要做的是让新进程拥有最后一个实例,所以当用户使用Close(X)按钮关闭VS时,它将销毁COM对象。没有AddRef()的EnvDTE的CoCreateInstance?

我尝试过几件事: 1.在我的CComPtr上调用Detach(),以便对象继续运行。当然,它的工作,但关闭VS关闭按钮并没有真正杀死进程(它仍然在任务管理器列表中运行)。 2.启动一个单独的VS进程,然后使用ROT来查找新实例。这很丑陋,因为在尝试查找COM对象的新实例之前,我必须等待无限的时间才能启动应用程序。 3.使用全局或静态CComPtr,并在应用程序关闭时手动销毁对象。我宁愿不这样做。

回答

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); 
0

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