9

Visual Studioパッケージでは、EnvDTE.DTE変数を使用する必要がありますが、常にnullとして返されます。多くのハックを読んだ後、それらはすべてOnShellPropertyChange()メソッド(IVsShellPropertyEvents)を使用すると言いますが、拡張機能の読み込みが完了しないかのように、起動しない場合があります。

私はVS2010を使用しており、VSSPROPID_ZombieとShellInitializedの両方をチェックしています-動作しません。:(

何か案は?これは私が使用しているコードです:

public int OnShellPropertyChange(int propid, object var) {
            if (propid == -9053 || (int) __VSSPROPID.VSSPROPID_Zombie == propid) { // -9053 = ShellInit
                try {
                    if ((bool) var == false) {
                        Dte = GetService(typeof (SDTE)) as DTE;
                        Flow.Dte = Dte;

                        var shellService = GetService(typeof (SVsShell)) as IVsShell;

                        if (shellService != null)
                            ErrorHandler.ThrowOnFailure(shellService.UnadviseShellPropertyChanges(_cookie));

                        _cookie = 0;
                    }
                } catch {

                }
            }

            return VSConstants.S_OK;
        }

編集:実験インスタンスでは、完全に機能し、初期化に約5秒かかります。ただし、VSIXとしてデプロイされると、起動しません。

4

4 に答える 4

31

次のコマンドを試してください。

dte = Package.GetGlobalService(typeof(DTE)) as DTE2;
于 2012-03-16T09:37:01.487 に答える
6

MEFコンポーネントがある場合、DTEオブジェクトに到達する最も簡単な方法は次のとおりです。

まず、Microsoft.VisualStudio.Shell.Immutable.10への参照を追加します。次に、のMEFインポートを追加しSVsServiceProviderます。このオブジェクトには、クエリ可能なGetServiceメソッドがありますDTE

[ImportingConstructor]
public MyComponent(SVsServiceProvider serviceProvider) {
  _DTE dte = (_DTE)serviceProvider.GetService(typeof(_DTE));
}
于 2010-09-25T05:15:57.920 に答える
5

ここにいくつかの問題があります。

  • 読みやすくするために、-9083ではなく__VSSPROPID4.VSSPROPID_ShellInitialized(Microsoft.VisualStudio.Shell.Interop.10.0で定義)を使用する必要があります。
  • ShellInitializedがtrueに設定されていることを確認する必要があります(ただし、Zombieがfalseになることを確認するのは正しいです)
  • ShellInitializedは、VSの起動時にtrueに変更されることに注意してください。パッケージが起動時に自動ロードするように登録されている場合は、それをチェックするのが正しいアプローチです(これは、VSが完全に準備が整う前に発生する可能性があります)。ただし、ほとんどのパッケージは起動時に自動ロードするのではなく、パッケージコードを必要とするユーザーアクションからオンデマンドでロードする必要があります次に、パッケージクラスのInitializeメソッドでDTEサービスを確認できます。
于 2010-09-25T17:22:09.753 に答える
3

すでに回答を選択していることは知っていますが、MEFを使用したくないと指定したので、完全を期すために別の回答を投稿すると思いました。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using EnvDTE;
using EnvDTE80;

namespace DTETesting
{
    class Program
    {
        const string ACTIVE_OBJECT = "VisualStudio.DTE.10.0";
        static void Main(string[] args)
        {
            EnvDTE80.DTE2 MyDte;
            MyDte = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject(ACTIVE_OBJECT);
            Console.WriteLine("The Edition is "+MyDte.Edition);
            Console.ReadLine();
        }
    }
}

于 2010-11-24T13:15:24.353 に答える