这些获取DTE2的方法之间有什么区别(Visual Studio 2013) [英] What is the difference between these methods of getting DTE2 (Visual Studio 2013)

查看:166
本文介绍了这些获取DTE2的方法之间有什么区别(Visual Studio 2013)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基于此问题我尝试了以下方法:

Based on this question I've tried the following:

EnvDTE80.DTE2 dte = ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE80.DTE2)) as EnvDTE80.DTE2;

没有运气,没有对象.

但是根据此MSDN文档,我尝试了以下操作.

But based on this MSDN doc I tried the following.

EnvDTE80.DTE2 dte = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.12.0");

那行得通,给了我DTE2对象.

That worked and gave me the DTE2 object.

从那里,我尝试了以下

From there, I tried the following this questin I've tried the following:

VersionControlExt vce = dte.GetObject("Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExt") as VersionControlExt;

没有运气,没有对象.

要注意的一件事是,对于最后一个问题,它说使用Microsoft.VisualStudio.TeamFoundation.Client命名空间.问题是,我找不到它.我什至已确保以相同的名称引用dll.我能够引用所有其他名称空间.

One thing to note, is per that last question, it says to use Microsoft.VisualStudio.TeamFoundation.Client namespace. The problem is, I can't find it. I've even made sure to reference the dll by the same name. I was able to reference all the other name spaces.

最后,我从 teamfoundation.blogspot 中尝试了以下操作.

Finally, I tried the following from teamfoundation.blogspot.

EnvDTE.IVsExtensibility extensibility = GetService(typeof(EnvDTE.IVsExtensibility)) as EnvDTE.IVsExtensibility;
EnvDTE80.DTE2 dte = extensibility.GetGlobalsObject(null).DTE as EnvDTE80.DTE2;
//Followed by this to get the Version
VersionControlExt vce = dte.GetObject("Microsoft.VisualStudio.TeamFoundation.VersionControl.VersionControlExt") as VersionControlExt;

这行得通.

因此,尽管我设法获得了DTE2并从中获得了VersionControlExt,但我觉得我已经进入了Cargo Cult程序员的领域,并且更愿意理解为什么这些都是构成获得DTE2的有效方法的原因.但他们的举止却有所不同.

So, while I've managed to get the DTE2 and from it the VersionControlExt, I feel I've entered the land of Cargo Cult programmers and would much prefer to understand why these were all posed as valid ways to get the DTE2 but they all behaved differently.

推荐答案

从扩展中获取DTE实例的正确方法是使用可扩展性API为该扩展提供的方法.

The correct way to get the DTE instance from within an extension is to use the way provided by the extensibility API for that extension.

  • 对于宏,它是全局DTE实例.
  • 对于加载项,必须实现IDTExtensibility2接口的OnConnection方法中传递的实例.
  • 对于软件包,它正在使用:

  • For macros it was the global DTE instance.
  • For add-ins it was the instance passed in the OnConnection method of the IDTExtensibility2 interface that add-ins had to implement.
  • For packages it is using:

base.GetService(typeof(EnvDTE.DTE))

base.GetService(typeof(EnvDTE.DTE))

(请注意,基本"是指MPF Package类,因此您正在使用可扩展性API.如果您像帖子中那样使用全局提供程序,那么您还将使用可扩展性API)

(notice that "base" refers to the MPF Package class so you are using the extensibility API. You are using also the extensibility API if you use the global provider as in your post)

但与此无关的是,标记为自动加载的软件包会发生以下两个问题:

but unrelated to that, is this couple of issues that happen with packages marked to autoload:

1)当启动VS时将包标记为自动加载(而不是在需要时加载)时,返回的DTE值将为空.

1) The returned DTE value will be null when the package is marked to autoload when VS is launched (rather than loading when required)

2)DTE不为空,但是某些属性(例如DTE.MainWindow)仍为空,因为VS实例尚未完全初始化.

2) DTE is not null, but some property such as DTE.MainWindow is still null because the VS instance is not fully initialized yet.

为防止这两种情况,您必须订阅VS IDE已完全初始化且未处于僵尸状态的通知.请参阅您必须使用的骇客技巧:如何:从Visual Studio包中获取EnvDTE.DTE实例.

To prevent those two cases you must subscribe to a notification that the VS IDE is fully initialized and not in a zombie state. See the horrible hack that you have to use: HOWTO: Get an EnvDTE.DTE instance from a Visual Studio package.

从扩展中获取DTE实例的不正确方法是使用COM自动化(通过.NET Framework API)而不是使用可扩展性API(MSDN文档中提到这种方法很可怕):

The incorrect way of getting the DTE instance from within an extension is to use COM automation (through the .NET Framework API) instead of using the extensibility API (and it is horrible that the MSDN docs mention this approach):

EnvDTE80.DTE2 dte = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.12.0");

因为COM自动化中的GetObject(ProgId)(或诸如.Marshal.GetActiveObject(ProgId)之类的.NET包装器)用于附加到所需ProgId的运行实例("VisualStudio.DTE.12.0")和如果您有多个正在运行的实例,则您的扩展程序可能会终止获得对另一实例的引用 !!.

because GetObject(ProgId) in COM automation (or .NET wrappers such as Marshal.GetActiveObject(ProgId)) are used to attach to a running instance of the required ProgId ("VisualStudio.DTE.12.0") and if you have have more than one running instance your extension could end getting a reference to the other instance!.

这篇关于这些获取DTE2的方法之间有什么区别(Visual Studio 2013)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆