12

「Visual Studio 用アドイン」ウィザードを使用して新しいアドイン プロジェクトを作成しましたが、現在、いくつかのイベント ハンドラーを追加しようとしています。

public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{
    _applicationObject = (DTE2)application;
    _addInInstance = (AddIn)addInInst;

    _applicationObject.Events.BuildEvents.OnBuildBegin += BuildEvents_OnBuildBegin;
    _applicationObject.Events.BuildEvents.OnBuildDone += BuildEvents_OnBuildDone;
    _applicationObject.Events.SelectionEvents.OnChange += SelectionEvents_OnChange;
    _applicationObject.Events.DocumentEvents.DocumentOpened += DocumentEvents_DocumentOpened;
    _applicationObject.Events.DocumentEvents.DocumentSaved += DocumentEvents_DocumentSaved;
}

しかし、私が何をしても、私のハンドラーは決して実行されません!

私は盲目ですか?これらのハンドラーを登録するために他に何かする必要がありますか?それともなぜ機能しないのですか?

4

2 に答える 2

22

あなたはガベージ コレクターの犠牲者のようです。参照: http://www.mztools.com/articles/2005/mz2005012.aspx

 private readonly BuildEvents _buildEvents;
 private readonly SelectionEvents _selectionEvents;
 private readonly DocumentEvents _documentEvents;
 private readonly Events _events;

 public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
 {
     _applicationObject = (DTE2)application;
     _addInInstance = (AddIn)addInInst;
     _events = _applicationObject.Events;

     _buildEvents = _events.BuildEvents;
     _buildEvents.OnBuildBegin += BuildEvents_OnBuildBegin;
     _buildEvents.OnBuildDone += BuildEvents_OnBuildDone;

     _selectionEvents = _events.SelectionEvents;
     _selectionEvents.OnChange += SelectionEvents_OnChange;

     _documentEvents = _events.DocumentEvents;
     _documentEvents.DocumentOpened += DocumentEvents_DocumentOpened;
     _documentEvents.DocumentSaved += DocumentEvents_DocumentSaved;
 }
于 2013-01-13T18:11:28.290 に答える
1

デバッガーでapplicationObjectを見ると、COMオブジェクトが表示されますが、xxxEventsクラスは表示されません(OnConnectionでコードを中断できない場合は、デバッグ時にアドインが読み込まれない可能性があります。ツールメニューを確認してください)

COMのイベントは、サーバー(VS)がそれらを起動するために呼び出す他の方向の別のCOMインターフェイス(この場合はいくつか)によって処理されます。

COMオブジェクトはCLRアセンブリと同様の型付きアセンブリの概念を持っていますが、内部的にはアンマネージコードであるため、マネージオブジェクトへのルートを保持することはできません

そのため、ネイティブCLRイベントとまったく同じようにデリゲートをCOMイベントにフックできますが、イベントはRCW(ランタイム呼び出し可能ラッパー)にフックされます。サーバーからRCWcomインターフェイスへのCOM参照がありますが、CLRルートがないと、RCWは最終的に破棄され、comインターフェイスがアンロードされます。その後、イベントはシンクされません。

よくわかりませんが、これは通常、イベントインターフェイスに直接関連付けられた単一のCOMオブジェクトを使用する場合に機能すると思います。そのため、DTECOMインターフェイスの構造が原因である可能性があります...

とにかく、他の人が言っているように、それを修正するには、アプリオブジェクトからBuildEvents、SelectionEvents、およびDocumentEventsクラスへのあらゆる種類の管理された参照が必要です。VSの複数のインスタンスは、アドインの個別のインスタンスをロードするため、静的オブジェクト参照のリストを追加して、それらをOnConnectに設定できます。

DTEイベントへのサブスクリプションが機能していないようです-イベントが呼び出されません

http://msdn.microsoft.com/en-us/library/k639e386.aspx

于 2013-01-14T11:15:05.407 に答える