1

これは、私が尋ねた別の質問に多少関連しています。パズルの最後のピースは、GetActiveObject() の代わりに CoCreateInstance() を使用することです。EnvDTE の既存のインスタンスを使用したくないので、VisualStudio の新しいインスタンスを適切に起動する CoCreateInstance を呼び出します。CoCreateInstance() は AddRef() を呼び出し、出力ポインターを CComPtr に格納します。これにより、破棄時に Release が適切に呼び出されます。この Release() が発生すると、見よ、VS のインスタンスが閉じる! もちろん、refcount が 0 であるためです。私がやりたいことは、新しいプロセスがその最後のインスタンスを所有するようにすることです。そのため、ユーザーが閉じる (X) ボタンで VS を閉じると、COM オブジェクトが破棄されます。

私が試したことはいくつかあります。確かに機能しますが、閉じるボタンで VS を閉じても、実際にはプロセスが強制終了されません (タスク マネージャー リストでまだ実行されています)。2. VS の別のプロセスを起動し、ROT を使用して新しいインスタンスを見つけます。COM オブジェクトの新しいインスタンスを見つけようとする前に、アプリケーションが起動するのを不確定な時間待たなければならないので、これは醜いです。3. グローバルまたは静的 CComPtr を使用し、アプリを閉じるときにオブジェクトを手動で破棄します。こういうやり方はやめた方がいい。

4

2 に答える 2

1

したがって、CoCreateInstance を使用して VisualStudio.DTE オブジェクトを作成する特定のケースについて、これを理解しました。返される DTE オブジェクトには、TRUE に設定できる UserControl プロパティがあります。これを 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 Eventを見てください。そのイベントをサブスクライブし、イベントが発生したときに Release() を呼び出すことができます。これには、サブスクライブするウィンドウ イベントを決定する必要があります。

于 2009-05-20T04:47:51.703 に答える