这些获取DTE2的方法有什么区别(Visual Studio 2013)

时间:2014-12-12 16:40:14

标签: c# visual-studio visual-studio-2013 tfs2013 visual-studio-extensions

根据this question,我尝试了以下内容:

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

没有运气,空对象。

但基于this MSDN doc,我尝试了以下内容。

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

这有效并给了我DTE2对象。

从那时起,我尝试了以下this questin我尝试了以下内容:

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

没有运气,空对象。

有一点需要注意的是,根据最后一个问题,它说要使用Microsoft.VisualStudio.TeamFoundation.Client命名空间。问题是,我无法找到它。我甚至确保用相同的名称引用dll。我能够引用所有其他名称空间。

最后,我尝试了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,但他们的行为都不同。

1 个答案:

答案 0 :(得分:6)

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

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

    base.GetService(typeof运算(EnvDTE.DTE))

(请注意" base"指的是MPF Package类,因此您使用的是可扩展性API。如果您在帖子中使用全局提供程序,那么您还使用了可扩展性API)

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

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

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

要防止这两种情况,您必须订阅VS IDE已完全初始化且不处于僵尸状态的通知。看看你必须使用的可怕的黑客:HOWTO: Get an EnvDTE.DTE instance from a Visual Studio package.

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

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&#34 ;)和如果您有多个正在运行的实例,您的扩展程序可能会结束获取对另一个实例的引用!。