CoCreateInstance for EnvDTE without AddRef ()?
This is somewhat related to another question I asked , which I understood a lot. The last piece of the puzzle is using CoCreateInstance () instead of GetActiveObject (). I don't want to use an existing EnvDTE instance, so I call CoCreateInstance, which properly starts a new VisualStudio instance. CoCreateInstance () calls AddRef () and stores the output pointer in CComPtr, which correctly calls Release on destruction. When this Release () happens, and lo and behold, the VS instance is closed! Of course this is because the refcount is zero. What I want to do is have a new process that has the most recent instance, so when the user closes VS with the Close (X) button, it will destroy the COM object.
There are several things I've tried: 1. Calling Detach () on my CComPtr, so the object lives. It works of course, however closing VS with the close button doesn't actually kill the process (it's still running in the task manager list). 2. Start a separate VS process and then use ROT to find a new instance. This is ugly because I have to wait an indefinite amount of time for the application to start before trying to find a new instance of the COM object. 3. Use a global or static CComPtr and manually destroy the object when my application exits. I would rather not do it this way.
a source to share
So I figured it out for the specific case of creating a VisualStudio.DTE object using CoCreateInstance. The returned DTE object has a UserControl property, which can be set to TRUE. If you set it to TRUE, then Release () CComPtr that contains the DTE object will not destroy the instance:
#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 );
a source to share
Have a look at WindowClosing Event . You can subscribe to this event, and when the event fires, call Release (). This will require you to define which window events should be subscribed to.
a source to share