惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

K
Kaspersky official blog
IT之家
IT之家
小众软件
小众软件
T
Tailwind CSS Blog
博客园 - 聂微东
V
Visual Studio Blog
博客园 - 三生石上(FineUI控件)
Hugging Face - Blog
Hugging Face - Blog
D
Docker
爱范儿
爱范儿
云风的 BLOG
云风的 BLOG
Google DeepMind News
Google DeepMind News
MongoDB | Blog
MongoDB | Blog
N
News and Events Feed by Topic
U
Unit 42
The Register - Security
The Register - Security
宝玉的分享
宝玉的分享
J
Java Code Geeks
H
Heimdal Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
酷 壳 – CoolShell
酷 壳 – CoolShell
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
博客园 - Franky
A
About on SuperTechFans
Webroot Blog
Webroot Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Recent Commits to openclaw:main
Recent Commits to openclaw:main
I
Intezer
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Project Zero
Project Zero
V
V2EX
博客园 - 司徒正美
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The GitHub Blog
The GitHub Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
A
Arctic Wolf
罗磊的独立博客
Forbes - Security
Forbes - Security
PCI Perspectives
PCI Perspectives
SecWiki News
SecWiki News
大猫的无限游戏
大猫的无限游戏
Simon Willison's Weblog
Simon Willison's Weblog
The Cloudflare Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
F
Fortinet All Blogs
博客园 - 【当耐特】
Microsoft Azure Blog
Microsoft Azure Blog

博客园 - sema

Netron开发快速上手(二):Netron序列化 发布一个免费开源软件-- PAD流程图绘制软件PADFlowChart Netron源码解读(一):GraphControl画布对象 Netron开发快速上手(一):GraphControl,Shape,Connector和Connection FileSystemWatcher事件多次触发的解决方法 IBatis.Net 中的数据类型转换 深入浅出之正则表达式(二) 深入浅出之正则表达式(一) 在.NET环境中实现每日构建(Daily Build)--NAnt篇 自动向网页Post信息并提取返回的信息 在C#中利用自动化模型操纵Word VS.NET 2003集成环境插件开发指南(二)----使用窗口 VS.NET 2003集成环境插件开发指南(一)----操纵菜单 后期写作计划 利用反射解决QueryString和Session中的参数绑定问题 开发Visual Studio风格的用户界面--MagicLibrary使用指南 Log4Net使用指南 一些写英文简历的词汇吧 关于一些大学课程名的中文翻译
VS.NET 2003集成环境插件开发指南(三)----操纵VS开发环境(完结篇)
sema · 2005-04-01 · via 博客园 - sema

前言:前段时间贴了两篇关于VS集成环境插件开发的一些知识,本篇讲了一些具体的应用,
也只是起个抛砖引玉的作用,因为还有许多插件开发方面的应用,需要大家自己探索了.
另外,我把插件开发的系列文章集合成了一个完整的Word文档,放在下载资源里了,方便大家查阅

VS.NET 2003集成环境插件开发指南(一)----操纵菜单

VS.NET 2003集成环境插件开发指南(二)----使用窗口

VS.NET2003插件开发-代码演示

VS.NET2003插件开发-文档

代码下载     文档下载

一、             操纵VS开发环境

VS.NET自动化模型涉及的面太广,本文只针对一些专题加以说明。

1、   利用代码模型浏览代码

l          获取代码模型对象

//获取当前正活动的文档

     Document activeDocument = applicationObject.ActiveDocument;

     if(activeDocument != null)

     {

         ProjectItem projectItem = activeDocument.ProjectItem;

         if(projectItem != null)

         {

              FileCodeModel fileCodeModel = projectItem.FileCodeModel;

              if(fileCodeModel != null)

              {

                   CodeElements codeElements = fileCodeModel.CodeElements;

                   if(codeElements != null)

                   {

                       foreach(CodeElement ce in codeElements)

                       {

                            result.AddRange(getCodeElements(ce));

                       }

                   }

              }

          }

}

说明:

上面的代码先从DTE对象(也即VS自动模型的根对象)获得当前正活动的文档对象

然后再根据文档对象获取和它关联的项目元素,这里的ProjectItem其实就是在解决方案资源管理器下面的项目文件夹对应的子项。可以是各种类型,如文件,文件夹等

再从项目元素获得关联的文件代码模型

根据文件代码模型获取其代码元素的集合CodeElementCollection,代码元素的父类为CodeElement,下面派生出许多的子类,代表具体的代码元素,分别有:

CodeNamespaceCodeClassCodeInterfaceCodeFunction

CodePropertyCodeVariableCodeDelegateCodeStructCodeEnum

代表着命名空间、类、接口、函数、属性、变量、委托、结构、枚举等类型的代码元素,某个CodeElement具体是何类型,可以根据CodeElement. vsCMElement枚举类型来判断,然后再显式转换成具体的子类即可

但是更进一步的代码元素,如函数体内的语句,好像还没有看到有方法检索。不过也可以利用一些其它的方法,比如CodeRush的程序集里面提供了一个StructuralParser程序集,用于C#的代码分析。如果谁有兴趣可以研究研究

l          根据具体类型检索代码元素(不再多做解释了):

         private ArrayList getCodeElements(CodeElement baseElement)

         {

              ArrayList result = new ArrayList();           

              switch(baseElement.Kind)

              {

                   case vsCMElement.vsCMElementNamespace:

                       CodeNamespace cn = (CodeNamespace) baseElement;

                       foreach(CodeElement element in cn.Members)

                       {

                            result.AddRange(getCodeElements(element));

                       }

                       break;

                   case vsCMElement.vsCMElementClass:            

                       CodeClass cc = (CodeClass) baseElement;

                       foreach(CodeElement element in cc.Members)

                       {

                            result.AddRange(getCodeElements(element));

                       }

                       break;

                   case vsCMElement.vsCMElementInterface:

                       CodeInterface ci = (CodeInterface) baseElement;

                       foreach(CodeElement element in ci.Members)

                       {

                            result.AddRange(getCodeElements(element));

                       }

                       break;

                   case vsCMElement.vsCMElementFunction:

                       result.Add(baseElement);

                       break;

                   case vsCMElement.vsCMElementProperty:

                       {

                            result.Add(baseElement);

                       }

                       break;

                   case vsCMElement.vsCMElementEvent:

                       {

                            result.Add(baseElement);

                       }

                       break;

                   case vsCMElement.vsCMElementDelegate:

                       {

                            result.Add(baseElement);

                       }

                       break;

                   case vsCMElement.vsCMElementStruct:

                       {

                            result.Add(baseElement);

                            CodeStruct cs = (CodeStruct) baseElement;

                            foreach(CodeElement element in cs.Members)

                            {

                                 result.AddRange(getCodeElements(element));

                            }

                       }

                       break;

                   case vsCMElement.vsCMElementEnum:

                       {

                            result.Add(baseElement);

                       }

                       break;

                   case vsCMElement.vsCMElementAttribute:

                       result.Add(baseElement);

                       break;

                   case vsCMElement.vsCMElementUsingStmt:

                       result.Add(baseElement);

                       break;

                   case vsCMElement.vsCMElementVariable:

                       result.Add(baseElement);

                       break;

              }

              return result;

         }

2、   操纵解决方案及其项目文档

l          获取当前被选中的项目

下面代码演示了鼠标点击一个项目,或项目中的子项时,如何得到该项目对象

public Project GetSelectedProject()

{

     Project project = null;

     //从被选中对象中获取工程对象

     EnvDTE.SelectedItem item = Application.SelectedItems.Item(1);

     if(item.Project != null)

     {//被选中的就是项目本生

         project = item.Project;

     }

     else

     {//被选中的是项目下的子项

         project = item.ProjectItem.ProjectItems.ContainingProject;

     }

     return project;

}

l          获取当前项目的所在目录

private string GetSelectedProjectPath()

{

         string path = "";

         //获取被选中的工程

         Project project = GetSelectedProject();

         if(project != null)

         {

                   //全名包括*.csproj这样的文件命

                   path = project.FullName;

         }

         //去掉工程的文件名

         path = Path.GetDirectoryName(path);

         return path;

}

l          将文件加入工程中

//获取被选中的工程

Project project = this.GetSelectedProject();

//将文件夹下的文件加入工程

project.ProjectItems.AddFromDirectory(sdir);

//将单个文件加入工程

project.ProjectItems.AddFromFile(nfile);

l          向项目中加入程序集引用

using VSLangProj;

private void AddReference(string assembly)

{

         Project project = GetSelectedProject();

         VSProject vsproject = null;

         if (project.Kind == PrjKind.prjKindCSharpProject)

         {

                   //工程类型为C#工程,projectObject成员转换为VSProject对象

                   vsproject = project.Object as VSProject;

         }

         if(vsproject != null)

         {

                  //获取C#工程的引用集

                   VSLangProj.References refers = vsproject.References;

                   if(refers != null)

                   {

                            //将程序集引用添加到工程中

                            refers.Add(assembly);

                   }

         }

}

3、   在代码编辑窗口操纵代码

这里不再详述,只是列出网上的资源,大家可以自行参考

二、             参考资料

http://www.knowdotnet.com/add-insmacros.html

msdn帮助目录:Visual Studio .NET-->使用 Visual Studio .NET 进行开发-->参考-->自动化与扩展性参考-->公共环境对象模型

三、             下载包说明:

CodeNavigator    :演示了如何通过代码模型浏览代码

GuidGen             :演示了WinForm窗口在VS.NET集成环境中的应用

MenuBrowser     :演示了工具窗口的应用以及例举菜单对象的名称

RegionsAddIn     :用于添加#Region标签,演示了如何操纵代码编辑窗口

STDTools           :演示了如何向工程里添加文件,以及程序集引用,以及在工程项目的右键菜单上添加自己的菜单项