Visual Studio 2008 可扩展性开发(三):Add-In运行机制解析(下)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

前言

在上篇Add-In运行机制解析(上)中,我分析了Add-In向导生成的代码,从中我们知道只要创建一个类库,它包含实现了IDTExtensibility2接口的类,然后为其建立.addin配置文件,就可以实现一个Add-In了。本文将更进一步,介绍Add-In的事件和生命周期,为今后的开发打下基础。

Add-In的事件

Add-In是事件驱动的,可以猜到的事件有加载、卸载、状态改变等等。事实上,这些事件都与IDTExtensibility2接口有关,也就是该接口的5个方法:

IDTExtensibility2

如果要了解这些方法如何执行,一个办法是在这些方法中加一个MessageBox,然后通过Add-In Manager进行一些操作,来观察事件的执行。现在使用Add-In向导建立一个简单的Add-In,名字为LifeCycleAddin,不要选择在Tools菜单显示命令,也不要选择在VS启动时加载。然后把Connect类的代码简化一下:

复制代码
C# Code - Add-In事件演示
/// <summary>The object for implementing an Add-in.</summary>
public class Connect : IDTExtensibility2
{
    
public Connect()
    {
    }

    
/// <summary>
    
/// Receives notification that the Add-in is being loaded.
    
/// </summary>
    public void OnConnection(object application, ext_ConnectMode connectMode, 
        object
 addInInst, ref Array custom)
    {
        _applicationObject 
= (DTE2)application;
        _addInInstance 
= (AddIn)addInInst;

        MessageBox.Show(
string.Format("Event: OnConnection, connectMode: {0}", connectMode));
    }

    
/// <summary>
    
/// Receives notification that the Add-in is being unloaded.
    
/// </summary>
    public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
    {
        MessageBox.Show(
string.Format("Event: OnDisconnection, connectMode: {0}", disconnectMode));
    }

    
/// <summary>
    
/// Receives notification when the collection of Add-ins has changed.
    
/// </summary>
    public void OnAddInsUpdate(ref Array custom)
    {
        MessageBox.Show(
"OnAddInsUpdate");
    }

    
/// <summary>
    
/// Receives notification that the host application has completed loading.
    
/// </summary>
    public void OnStartupComplete(ref Array custom)
    {
        MessageBox.Show(
"OnStartupComplete");
    }

    
/// <summary>
    
/// Receives notification that the host application is being unloaded.
    
/// </summary>
    public void OnBeginShutdown(ref Array custom)
    {
        MessageBox.Show(
"OnBeginShutdown");
    }
    
private DTE2 _applicationObject;
    
private AddIn _addInInstance;
}
复制代码


每个方法的注释说明了相应的事件何时触发。OnConnection是在Add-In加载的时候;OnDisconnection是在Add-In卸载的时候;OnAddInsUpdate是在所有Add-In的集合状态发生改变的时候;OnStartupComplete是在宿主环境加载完成的时候;OnBeginShutdown则是在宿主环境将被关闭的时候。现在编译项目,然后关闭VS。

打开VS,开始第一回合的观察。由于没有选择在VS启动时加载,所以现在什么也不会发生。打开Add-In Manager,对于LifeCycleAddin,将其设置为可用,确定。这时触发了OnConnection,connectMode为ext_cm_AfterStartup,也就是说在VS启动之后才加载的;然后还触发了OnAddinsUpdate,因为LifeCycleAddin的状态改变了。再次打开Add-In Manager,对于LifeCycleAddin,将其设置为启动时加载,确定,再次触发OnAddinsUpdate。现在关闭VS,由于Add-In已经加载,所以会触发OnBeginShutdown,然后是OnDisconnection,说明Add-In已经被卸载。

打开VS,开始第二回合的观察。由于选择了在VS启动时加载,所以此时触发了OnConnection,connectMode为ext_cm_Startup,也就是说是在VS启动时加载的;之后连续触发了OnAddinsUpdate和OnStartupComplete,只有设置为在VS启动时加载才可能触发该事件。至此,5个事件都已经触发过了。

比较有意思的是OnAddinsUpdate。现在打开Add-In Manager,改变另一个Add-In的设置,点击确定,该事件也会触发,这就是前面所说的“所有Add-In的集合状态发生改变的时候”。

由前面的介绍可以了解到,实现IDTExtensibility2接口是每个Add-In的核心所在。但是仅仅这些显然还不够。我们不仅需要知道VS合适启动、卸载或改变了Add-In,我们还要能够在这些时候访问VS,否则开发VS的Add-In也就没意义了。这就用到了VS的自动化对象模型(Automation Object Model)

VS自动化对象模型简介

在Connect.cs文件的顶部using部分,可以看到两个命名空间:EnvDTE和EnvDTE80。EnvDTE表示开发环境工具扩展(Environment Development Tools Extensibility,常简称为DTE),就是在这里定义了VS的自动化对象模型(以下简称AOM)。而EnvDTE80的80表示8.0版本的AOM,其实还有一个表示9.0版本的EnvDTE90,但没有引用进来。

简单说一下它们的关系。EnvDTE表示VS2005之前的DTE版本,在每个版本中微软都会修复一些bug或添加新的功能,到了VS2005,微软使用了EnvDTE80表示新版本的变化(包括修复和增强),同时对于那些旧版本中已经存在的类,在后面加了一个数字2表示该类的新版本,如CodeFunction2表示是EnvDTE80中的新类型,而CodeFunction则表示EnvDTE中对应的那个类。EnvDTE90与此类似,比如Solution3、Solution2和Solution分别表示三个版本中表示解决方案的类。对于这些不同版本的类,微软的做法是用新版本的类继承旧的版本,然后进行扩展

但是相对于EnvDTE80与EnvDTE之间的变化,EnvDTE90的变化要小很多。大部分时候EnvDTE80就够用了,所以默认情况下,Connect.cs文件没有引用EnvDTE90。以后当你看到带着2或3后缀的类型,就能明白它的来历了。下面是AOM的结构图(点击查看大图):

点击查看大图

不出意外的是,结构很复杂。原因有二:首先VS本身很复杂,DTE用来表示VS中的元素,不能不复杂;其次,AOM和DTE源自COM,在.NET和COM间的互操作增强一些额外的工作。不过不用担心,这些类封装得非常之好,用起来还是比较容易的。

这个类型结构的顶端是DTE/DTE2,它是所有其它类型的容器。DTE主要包含5部分内容:解决方案和项目、命令(Command)、事件、文档、调试器,通过这些,我们就能够操作VS的方方面面(可以先看一下图中类的名字)。在后续的随笔中,你将看到这些内容的详细用法。

再议IDTExtensibility2接口

现在回到IDTExtensibility2接口,仔细了解一下它的各个方法。

1)OnConnection

在实现这个接口的时候,我们需要获得DTE对象,这样才能操作VS,这件事要在OnConnection中去做。

C# Code - Method Signature
public void OnConnection(object application, ext_ConnectMode connectMode, 
            
object addInInst, ref Array custom)


application参数
持有AOM根对象的引用,它同时实现了EnvDTE.DTE和EnvDTE80.DTE2接口,所以在我们的例子中,它被转换为DTE2。connectMode参数告诉Add-In是以何种方式加载的,它的值来自Extensibility.ext_ConnectMode枚举:

  • ext_cm_AfterStartup:在VS启动之后加载
  • ext_cm_Startup:在VS启动之时加载
  • ext_cm_External:在VS外部加载(VS已经不再使用该值)
  • ext_cm_CommandLine:从命令行加载
  • ext_cm_Solution:在解决方案内加载
  • ext_cm_UISetup:在建立用户界面时加载

我们可以根据该参数值的不同进行相应的操作,比如如果是ext_cm_UISetup,可以在菜单上添加一条命令(就像Add-In向导所做的那样)。

Add-In本身是AddIn接口的一个实例,addInInst参数持有该实例的引用,我们可以将该值保存下来备用。最后,IDTExtensibility2接口的每个方法都有一个custom参数,Add-In的宿主环境可以通过它来传递宿主相关的信息,不过VS总是传递一个空的数组(汗。。。)。

2)OnStartupComplete

OnStartupComplete事件仅仅在Add-In随VS启动加载的时候才会触发。

C# Code - Method Signature
void OnStartupComplete(ref Array custom)


如果一个Add-In随VS启动而加载,OnConnection并非总是进行初始化的好地方——比如,Add-In加载的较早,而Add-In需要访问的VS组件尚未加载完毕。

3)OnAddInsUpdate

C# Code - Method Signature
void OnAddInsUpdate(ref Array custom)


在某个Add-In被加载或卸载的时候,OnAddInsUpdate事件会触发。OnAddInsUpdate事件没有提供被加载或卸载Add-In的信息,不过我们有办法获取到。大体原理是:通过DTE.AddIns/DTE2.AddIns集合我们能够获取到所有的Add-In,里面的元素类型为AddIn,AddIn有个Connected属性,用以表示该Add-In是否处于加载状态,我们在首次触发OnAddInsUpdate事件的时候记录所有Add-In的状态,在下次触发的时候就知道那些Add-In状态改变了,这里就不再给出代码了。

4)OnBeginShutDown

C# Code - Method Signature
void OnBeginShutdown(ref Array custom)


如果在一个Add-In运行的时候关闭VS,OnBeginShutDown事件会触发。我们在这个时候可以做一些必要的清理工作。

5)OnDisconnection

C# Code - Method Signature
void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)


在Add-In的生命周期结束的时候,OnDisconnection事件会触发。它跟OnBeginShutDown事件的不同之处在于,这里结束的是Add-In而不是VS。disconnectMode参数的值来自Extensibility.ext_DisconnectMode枚举:

  • ext_dm_HostShutdown:因为VS关闭而卸载
  • ext_dm_UserClosed:在VS运行时卸载
  • ext_dm_UISetupComplete:在用户界面创建完毕后卸载
  • ext_dm_SolutionClosed:在解决方案关闭时卸载

它的作用类似于ext_ConnectMode,我们可以根据Add-In卸载方式的不同采取不同的动作。

唔,至此Add-In的事件和生命周期介绍完毕。

我们身在何处?

本文主要介绍了VS Add-In的事件和生命周期,通过这些知识,我们能够知道在何时获取需要的信息;同时还简单介绍了VS自动化对象模型。加上Add-In运行机制解析(上),我们应当对Add-In的运行机制有个基本的了解,为接下来的开发打下基础。到现在我们还不足以写出真正有用的Add-In,从下一篇开始我将介绍如何开发真正有用的Add-In。

参考

《Professional Visual Studio® 2008 Extensibility》
《Working with Microsoft Visual Studio® 2005》


本文转自一个程序员的自省博客园博客,原文链接:http://www.cnblogs.com/anderslly/archive/2009/03/03/vs-addin-explained-part2.html,如需转载请自行联系原作者。

目录
相关文章
|
19天前
|
安全 前端开发 Android开发
探索移动应用与系统:从开发到操作系统的深度解析
在数字化时代的浪潮中,移动应用和操作系统成为了我们日常生活的重要组成部分。本文将深入探讨移动应用的开发流程、关键技术和最佳实践,同时分析移动操作系统的核心功能、架构和安全性。通过实际案例和代码示例,我们将揭示如何构建高效、安全且用户友好的移动应用,并理解不同操作系统之间的差异及其对应用开发的影响。无论你是开发者还是对移动技术感兴趣的读者,这篇文章都将为你提供宝贵的见解和知识。
|
21天前
|
PHP 开发者 UED
PHP中的异常处理机制解析####
本文深入探讨了PHP中的异常处理机制,通过实例解析try-catch语句的用法,并对比传统错误处理方式,揭示其在提升代码健壮性与可维护性方面的优势。文章还简要介绍了自定义异常类的创建及其应用场景,为开发者提供实用的技术参考。 ####
|
25天前
|
存储 缓存 监控
后端开发中的缓存机制:深度解析与最佳实践####
本文深入探讨了后端开发中不可或缺的一环——缓存机制,旨在为读者提供一份详尽的指南,涵盖缓存的基本原理、常见类型(如内存缓存、磁盘缓存、分布式缓存等)、主流技术选型(Redis、Memcached、Ehcache等),以及在实际项目中如何根据业务需求设计并实施高效的缓存策略。不同于常规摘要的概述性质,本摘要直接点明文章将围绕“深度解析”与“最佳实践”两大核心展开,既适合初学者构建基础认知框架,也为有经验的开发者提供优化建议与实战技巧。 ####
|
25天前
|
缓存 NoSQL Java
千万级电商线上无阻塞双buffer缓冲优化ID生成机制深度解析
【11月更文挑战第30天】在千万级电商系统中,ID生成机制是核心基础设施之一。一个高效、可靠的ID生成系统对于保障系统的稳定性和性能至关重要。本文将深入探讨一种在千万级电商线上广泛应用的ID生成机制——无阻塞双buffer缓冲优化方案。本文从概述、功能点、背景、业务点、底层原理等多个维度进行解析,并通过Java语言实现多个示例,指出各自实践的优缺点。希望给需要的同学提供一些参考。
43 7
|
23天前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
24天前
|
Java 数据库连接 开发者
Java中的异常处理机制:深入解析与最佳实践####
本文旨在为Java开发者提供一份关于异常处理机制的全面指南,从基础概念到高级技巧,涵盖try-catch结构、自定义异常、异常链分析以及最佳实践策略。不同于传统的摘要概述,本文将以一个实际项目案例为线索,逐步揭示如何高效地管理运行时错误,提升代码的健壮性和可维护性。通过对比常见误区与优化方案,读者将获得编写更加健壮Java应用程序的实用知识。 --- ####
|
26天前
|
前端开发 Android开发 UED
移动应用与系统:从开发到优化的全面解析####
本文深入探讨了移动应用开发的全过程,从最初的构思到最终的发布,并详细阐述了移动操作系统对应用性能和用户体验的影响。通过分析当前主流移动操作系统的特性及差异,本文旨在为开发者提供一套全面的开发与优化指南,确保应用在不同平台上均能实现最佳表现。 ####
27 0
|
7月前
Visual Studio 2022 中VLD库如何安装
Visual Studio 2022 中VLD库如何安装
737 1
|
7月前
Visual Studio 2022 中VLD库如何安装
Visual Studio 2022 中VLD库如何安装
715 0
|
6月前
|
IDE 开发工具 C语言
Visual Studio 2017 安装及使用(新手)
Visual Studio 2017 安装及使用(新手)
1308 0

推荐镜像

更多