VSPackge插件系列:如何正确获取DTE
做VS插件开发,不得不了解DTE,有了DTE我们就可以与VS交互了,比如说获取当前选择的文件,比如说获取当前主窗口,比如说获取编译器等等,关于DTE接口更多的说明我把接口地址贴出来方便大家查阅。
http://technet.microsoft.com/zh-cn/library/envdte.dte(v=vs.100)
如何正确的获取DTE呢?
以下是从网上找到的一些方法
EnvDTE80.DTE2 myDTE2 = (EnvDTE80.DTE2)Microsoft.VisualBasic.Interaction.CreateObject("VisualStudio.DTE.9.0", "");
EnvDTE80.DTE2 _dte2 = (EnvDTE80.DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.11.0");
Type visualStudioType = Type.GetTypeFromProgID("VisualStudio.DTE.11.0");
EnvDTE80.DTE2 _dte2 = Activator.CreateInstance(visualStudioType) as EnvDTE80.DTE2;
参考地址:http://msdn.microsoft.com/zh-cn/library/68shb4dw(VS.80).aspx
这些代码在我做测试的时候并不能很好的工作,比如说"VisualStudio.DTE.9.0",这个字符串,很明显跟VS版本有关,这样针对不同版本的VS就有所不同,比如VS2010获取的是10.0,VS2012获取的是11.0等等,另外一个更加令人蛋疼的问题是,以上方法获取的DTE只适合开一个VS的情况,当开多个VS的时候我们获取的DTE并不是我们当前打开项目的DTE。所以我查找一些资料最终在以下这篇文章找到答案http://social.msdn.microsoft.com/Forums/zh-CN/09fb98aa-31d0-45e2-ace2-35b6d59e855a/vsx-faq-vspackagedte。那我们就可以用以下代码获取。
EnvDTE80.DTE2 _dte2 = (EnvDTE80.DTE2)ServiceProvider.GlobalProvider.GetService(typeof(EnvDTE.DTE));
这种方式可以正确的获取DTE,并且在多个vs中不存在混乱的现象,也没有DET版本的限制。
此方法还有限制,就是必须在vs初始化完成获取Dte,否则获取的dte为空,
以下文章是一种解决方法
为了防止文章丢失我拷贝到下边,以供参考
Dr. eX: Why does GetService(typeof(EnvDTE.DTE)) return null?
|
protectedoverridevoid Initialize() { base.Initialize(); this.dte = GetService(typeof(DTE)) asDTE; …… } |
And then realize later on that this.dte is null?
A number of Visual Studio integrators have encountered just this problem in the past, and having recently seen this problem pop up again, it’s definitely past due for Dr. eX to blog about this.
The reason the above GetService call can sometimes return null, is due to the environment not being fully loaded and initialized. When the IDE is in this state it’s said to be in a “zombie” state. The IDE actually tracks this state with the VSPROPID_Zombie property.
To work around this problem, you simply need to defer the code in your Initialize method, until the VSPROPID_Zombie property has been set to false. To do this, your package should implement IVsShellPropertyChanges interface, and execute your initialization code from your IVsShellPropertyChanges.OnShellPropertyChange implementation. For example:
| public class MyPackage : Package, IVsShellPropertyEvents
{ DTE dte; uint cookie; protected override void Initialize() { base.Initialize(); // set an eventlistener for shell property changes IVsShell shellService = GetService(typeof(SVsShell)) as IVsShell; if (shellService != null) ErrorHandler.ThrowOnFailure(shellService.AdviseShellPropertyChanges(this,out cookie)); // code not depending on zombie state …….. } public int OnShellPropertyChange(int propid, object var) { // when zombie state changes to false, finish package initialization if ((int)__VSSPROPID.VSSPROPID_Zombie == propid) { if ((bool)var == false) { // zombie state dependent code this.dte = GetService(typeof(SDTE)) as DTE; // eventlistener no longer needed IVsShell shellService = GetService(typeof(SVsShell)) as IVsShell; if (shellService != null) ErrorHandler.ThrowOnFailure(shellService.UnadviseShellPropertyChanges(this.cookie)); this.cookie = 0; } } return VSConstants.S_OK; } } |
VSPackge插件系列:如何正确获取DTE的更多相关文章
- VSPackge插件系列:常用IDE功能的封装
继上一篇VSPackge插件系列简单介绍如何正确的获取DTE之后,就一直没发VSPackge插件系列的文章了,最近同事也想了解如何在代码中与VS交互,特发一篇文章示例一些简单功能是如何调用,也以备以后 ...
- VSPackge插件系列:简单文本编辑器的实现
相比其它开发环境,VS的好用就不用多说了,尽管VS很人性化,但是针对具体的我们想实现的功能时,会力不从心,也许会有很多现成的插件,但是作为一名程序员,我还是喜欢自己去写一些东西,因为这样能随心所欲的想 ...
- document.documentElement.clientHeight 和 $(window).height() 无法正确获取页面可视区高度
背景: 弹出层插件(自适应) 实现过程中突然发现在获取可视区高度时,无论document.documentElement.clientHeight 还是 $(window).height()都无法正确 ...
- 一用钟情的VS插件系列总目录(值得收藏)
关于插件,大家的印象可能很多,比如开发者经常使用的Chrome浏览器的扩展程序,某个软件的一个扩展程序等等.我们使用插件的目的是为了提高我们的某些方面的工作效率或者让我们的软件源(Chrome浏览器等 ...
- Jquery插件实现点击获取验证码后60秒内禁止重新获取
通过jquery.cookie.js插件可以快速实现“点击获取验证码后60秒内禁止重新获取(防刷新)”的功能 先到官网(http://plugins.jquery.com/cookie/ )下载coo ...
- 使用ExpandableListView——当有Group选项展开时,如何正确获取长按的Group选项。
当我们使用ExpandableListView时,实现点击一个GroupView则展开ChidView,那么这个时候,Adapter的大小前后是有变化的. 例如:假设有20个GroupView,每个G ...
- 【原创】书本翻页效果booklet jquery插件系列之简介
booklet jquery插件系列之简介 本文由五月雨恋提供,转载请注明出处. 一.安装 1.添加CSS和Javascript 添加booklet CSS文件到你的页面. <link rel= ...
- IntelliJ IDEA插件系列
参考: IntelliJ IDEA插件系列 1. activate-power-mode 和 Power mode II 根据Atom的插件activate-power-mode的效果移植到IDEA上 ...
- 使用 PySide2 开发 Maya 插件系列 总览
使用 PySide2 开发 Maya 插件系列 总览 使用 PySide2 开发 Maya 插件系列一:QT Designer 设计GUI, pyside-uic 把 .ui 文件转为 .py 文件 ...
随机推荐
- C# 多线程 方法,类的标记
[MethodImplAttribute(MethodImplOptions.Synchronized)] 此标记可用于方法,将一个方法标记为单线程进入,但在多个实例的时候仍有可能导致问题,比较有共享 ...
- sprintf的缓冲区溢出
sprintf的缓冲区溢出 分类: 技术2010-03-07 15:26 362人阅读 评论(0) 收藏 举报 今天,调试sector的时候遇到一个特奇怪的问题,程序会在取string的c_str() ...
- HTML-css selector
Css selector 基本有三种 HTML(TAG)selector , ID selector , Class selector css selector 综合使用 : 重用,子选择器,组选择器 ...
- JQuery原理
1.简单模拟JQuery工作原理 (function(window){ var JQuery ={ a: function(){ alert('a'); }, b: function(){ alert ...
- DataRow数组 转 datatable
DataTable tmpdt = dt.Clone(); DataRow[] drs = dt.Select("legnbr="+legNbr); ) { tmpdt = drs ...
- Web缓存基础:术语、HTTP报头和缓存策略
简介 对于您的站点的访问者来说,智能化的内容缓存是提高用户体验最有效的方式之一.缓存,或者对之前的请求的临时存储,是HTTP协议实现中最核心的内容分发策略之一.分发路径中的组件均可以缓存内容来加速后续 ...
- Hadoop,HBase,Zookeeper源码编译并导入eclipse
基本理念:尽可能的参考官方英文文档 Hadoop: http://wiki.apache.org/hadoop/FrontPage HBase: http://hbase.apache.org/b ...
- hdu 1597 find the nth digit
find the nth digit Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- [css]display: table-cell,用div做分列布局
table-cell我们却能用得到,而且是用它来干一件很重要的事情——多列布局. 多列布局在css中有多重要就不用我说了吧,传统模式下大家都使用float来解决这一问题,但是float写出来的东西代码 ...
- MAC 终端 显示隐藏文件 关闭显示隐藏文件
1.显示隐藏文件夹显示:defaults write com.apple.finder AppleShowAllFiles -bool true (1)复制“defaults write com.ap ...