zoukankan      html  css  js  c++  java
  • VS.NET 2003集成环境插件开发指南(三)操纵VS开发环境(完结篇)

    前言:前段时间贴了两篇关于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           :演示了如何向工程里添加文件,以及程序集引用,以及在工程项目的右键菜单上添加自己的菜单项

  • 相关阅读:
    Python补充06 Python之道
    java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括InputStream)
    java io系列01之 "目录"
    字符编码(ASCII,Unicode和UTF-8) 和 大小端
    Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(7) TimeZone
    Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(6) Locale
    Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(5) SimpleDateFormat
    Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(4) DateFormat
    Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(3) Date
    Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(2) 自己封装的Calendar接口
  • 原文地址:https://www.cnblogs.com/dragon/p/130204.html
Copyright © 2011-2022 走看看