VSIX:获取DTE对象

hb.*_*hb. 9 .net c# visual-studio-2010 visual-studio vsix

我的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;
        }
Run Code Online (Sandbox Code Playgroud)

编辑:在实验实例下,它完美地工作,初始化大约需要5秒钟.但是,一旦部署为VSIX - 它根本不会触发.

小智 27

请尝试以下命令:

dte = Package.GetGlobalService(typeof(DTE)) as DTE2;
Run Code Online (Sandbox Code Playgroud)

  • 这个适用于我,只需要在项目中添加对Microsoft.VisualStudio.Shell.dll的引用. (2认同)

Jar*_*Par 6

如果您有MEF组件,最简单的到达DTE对象的方法如下

首先添加对Microsoft.VisualStudio.Shell.Immutable.10的引用.然后添加MEF导入SVsServiceProvider.该对象具有可以查询的GetService方法DTE

[ImportingConstructor]
public MyComponent(SVsServiceProvider serviceProvider) {
  _DTE dte = (_DTE)serviceProvider.GetService(typeof(_DTE));
}
Run Code Online (Sandbox Code Playgroud)


Aar*_*ten 6

我在这看到几个问题:

  • 你真的应该使用__VSSPROPID4.VSSPROPID_ShellInitialized(在Microsoft.VisualStudio.Shell.Interop.10.0中定义)而不是-9083来提高可读性
  • 您应该检查ShellInitialized是否设置为true(尽管检查Zombie是否为false是正确的)
  • 请记住,ShellInitialized将变成真正的一次 ...在VS.启动 如果您的软件包在启动时注册为自动加载(这可能在VS完全准备就绪之前发生),则检查它是正确的方法.然而,大多数包应该不会在启动时自动加载,而是按需从需要你的包代码一些用户操作而加载.然后,您可以在包类Initialize方法中检查DTE服务.