1

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

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

4

2 回答 2

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 );
于 2009-06-16T22:47:11.663 回答
0

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

于 2009-05-20T04:47:51.703 回答