VSTO学习笔记(三) 开发Office 2010 64位COM加载项

原文: VSTO学习笔记(三) 开发Office 2010 64位COM加载项

一、加载项简介

Office提供了多种用于扩展Office应用程序功能的模式,常见的有:

1、Office 自动化程序(Automation Executables)

2、Office加载项(COM or Excel Add-In)

3、Office文档代码或模板(Code Behind an Office Document or Template)

4、Office 智能标签(Smart Tags)

本次我们将学习使用VSTO 4.0编写一个简单的Office COM 加载项,构建于Office 2010 x64.

示例代码下载

本系列所有示例代码均在 Visual Studio 2010 Ultimate RC 和 Office 2010 Professional Plus Beta x64 中测试通过。

 

二、为什么要使用加载项

Office加载项提供了一种扩展应用程序核心功能的机制,由此添加的功能可以在整个应用程序或单个应用程序中使用,极大的扩充了Office的应用领域:

1、扩展现有功能:对于特定需求,特别是和业务紧密相关的需求,如果能够以加载项的方式在Office中解决,那么将节省软件成本、培训成本等。

2、数据整合:随着Office由办公平台正式转变为一个计算平台之后,将Office与其他平台进行整合的需求也变得愈来愈频繁。如将Web服务器中数据导入到Excel中,将SAP系统中数据导入到Excel中,生成日报表等。

 

三、COM加载项的工作原理

要使用COM加载项,必须要在注册表中写入相应的信息。Office 要判断使用哪些加载项时,以Excel为例,需要查看注册表中的两个位置:

(PS:推荐一个注册表编辑器Registry Workshop,功能很强大,支持64位,可以在这里下载)

1、HKEY_CURRENT_USER\Software\Microsoft\Office\Excel\AddIns

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

这个位置是针对于特定用户的,也是推荐的位置。在该位置注册的COM加载项将出现在Office中的COM加载项对话框中:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

在该位置,有几项是必备的。

1)FriendlyName:字符串值,包含了显示在COM对话框中的COM加载项的名称;

2)Description:字符串值,包含了COM加载项的简短描述信息;

3)LoadBehavior:DWORD类型,用于描述COM加载项的加载方式,通常设置为3(1 + 2).

描述

0

断开,不加载COM加载项

1

连接,加载 COM加载项

2

启动时加载,主应用程序启动时加载并连接COM加载项

8

需要时加载,主应用程序需要(触发加载事件)时加载并连接COM加载项

16

首次连接,用户注册加载项后,首次运行主应用程序时加载并连接COM加载项

 

除了上面的三个,还需要在HKEY_CLASSES_ROOT\CLSID下创建几个注册表项:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

 

2、HKEY_LOCAL_MACHINE\Software\Microsoft\Office\Excel\AddIns

这个位置是针对于所有用户的,但是这些加载项对用户隐藏,即不会出现在COM加载项对话框中。

 

这些注册表项如果纯手工写将会非常麻烦,而且容易出错,幸运的是,Visual Studio提供了一组模板来方便的创建Office加载项,但是我们还是应该理解这些注册表项及其代表含义。

 

四、理解IDTExtensibility2接口

所有Office应用程序都是用IDTExtensibility2接口与COM加载项进行通信,该接口提供了一种通用的初始化机制,并具有在Office应用程序的对象模型中传递数据的能力,因此COM加载项可以与Office应用程序通信。

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

IDTExtensibility2接口并不复杂,但是对于标注COM加载项的加载顺序,以及它在何处影响我们编写的代码来说,此接口至关重要。Office在对COM加载项进行实例化时,会创建主Connect类,注意不能用Connect的构造函数创建类的实例,应该用OnConnection方法;类似的,加载项的关闭不能调用析构函数,而要用OnDisconnection方法。

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

 

五、ExcelCOMAddInDemo

现在我们来动手开发一个简单的Excel COM Add-In.

1、新建一个Share Add-In项目:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

2、在弹出的项目向导中,点击【Next】:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

3、选择你所熟悉的语言,点击【Next】:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

4、选择COM 加载项的目标宿主,点击【Next】:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

 

5、输入Add-In的名称和描述,点击【Next】:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

6、选择"启动时加载",点击【Next】:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

7、点击【Finish】:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

8、项目建立完成后会自动添加一个安装项目,它会负责安装生成的COM加载项,处理注册表的信息等,无需我们手动参与。

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

64-bit Support and Code Compatibility

Office 2010 will ship in both 32- and 64-bit versions. 64-bit is particularly significant to some Excel applications, which hit a wall today in terms of available memory address space. This is an important topic in itself, which we have covered here.

Excel workbooks can be freely opened and edited in both 32- and 64-bit Excel; there is nothing architecture specific in a saved workbook. For custom code solutions, however, 64-bit Excel introduces some challenges:

  • ActiveX controls need to be ported – they need a 64-bit version to work in a 64-bit process. This includes Microsoft's own controls, of which many have been ported. We are evaluating the popularity and criticality of the remaining ones for possible porting.
  • COM add-ins, similarly, need to be compiled for 64-bit in order to work in 64-bit Excel.
  • XLL add-ins also need to be compiled for 64-bit, and the new Excel 2010 XLL SDK supports that.
  • VBA: Embedded VBA code gets re-compiled when the containing Excel workbook is opened on a new platform; 64-bit Excel now includes a 64-bit version of VBA. So most VBA code just works in 64-bit. However, a subset of VBA solutions needs some tweaking. It has to do with declarations and calls to external APIs with pointers/handles in the parameter list. VBA7, the new version of VBA that ships with Office 2010, supports the development of code that can run in both 32- and 64-bit Office.

摘自Excel 2010官方博客,可以看出,在Office 2010 x64中,必须编写64位的COM Add-In.

这不是问题,稍后我们将看到如何编译64位的COM Add-In和生成64位的安装文件。

9、设置项目属性:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

在【Build】标签中,将【Platform】设置为:Active(x64),取消【Register for COM】的选择:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

在【Debug】标签中,将【Platform】设置为:Active(x64),同时将【Start Action】设置为Excel的安装路径,这样做可以启动Excel来调试COM Add-In:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

配置编译选项:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

配置安装项目属性:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

10、我们要做的是在Excel 的Ribbon中添加一个按钮,点击后弹出一则欢迎信息。

首先添加引用:

Microsoft.Office.Interop.Excel

System.Windows.Forms

打开Connect.cs,添加如下代码:

 

代码
namespace  ExcelCOMAddInDemo
{
    
using  System;
    
using  Extensibility;
    
using  System.Runtime.InteropServices;
    
using  Microsoft.Office.Interop.Excel;
    
using  Microsoft.Office.Core;
    
using  System.Windows.Forms;

    
#region  Read me for Add-in installation and setup information.
    
//  When run, the Add-in wizard prepared the registry for the Add-in.
    
//  At a later time, if the Add-in becomes unavailable for reasons such as:
    
//    1) You moved this project to a computer other than which is was originally created on.
    
//    2) You chose 'Yes' when presented with a message asking if you wish to remove the Add-in.
    
//    3) Registry corruption.
    
//  you will need to re-register the Add-in by building the ExcelCOMAddInDemoSetup project, 
    
//  right click the project in the Solution Explorer, then choose install.
     #endregion

    
///   <summary>
    
///    The object for implementing an Add-in.
    
///   </summary>
    
///   <seealso class='IDTExtensibility2' />
    [GuidAttribute( " DDC49E0C-03FE-4134-9829-65EF0351CECE " ), ProgId( " ExcelCOMAddInDemo.Connect " )]
    
public   class  Connect : Object, Extensibility.IDTExtensibility2
    {
        
private  Microsoft.Office.Interop.Excel.Application applicationObject;
        
private  Microsoft.Office.Core.COMAddIn addInInstance;
        
private  CommandBarButton simpleButton;
        
///   <summary>
        
///         Implements the constructor for the Add-in object.
        
///         Place your initialization code within this method.
        
///   </summary>
         public  Connect()
        {
        }

        
///   <summary>
        
///       Implements the OnConnection method of the IDTExtensibility2 interface.
        
///       Receives notification that the Add-in is being loaded.
        
///   </summary>
        
///   <param term='application'>
        
///       Root object of the host application.
        
///   </param>
        
///   <param term='connectMode'>
        
///       Describes how the Add-in is being loaded.
        
///   </param>
        
///   <param term='addInInst'>
        
///       Object representing this Add-in.
        
///   </param>
        
///   <seealso class='IDTExtensibility2' />
         public   void  OnConnection( object  application, Extensibility.ext_ConnectMode connectMode,  object  addInInst,  ref  System.Array custom)
        {
            applicationObject 
=  application  as  Microsoft.Office.Interop.Excel.Application;
            addInInstance 
=  addInInst  as  Microsoft.Office.Core.COMAddIn;
        }

        
///   <summary>
        
///      Implements the OnDisconnection method of the IDTExtensibility2 interface.
        
///      Receives notification that the Add-in is being unloaded.
        
///   </summary>
        
///   <param term='disconnectMode'>
        
///       Describes how the Add-in is being unloaded.
        
///   </param>
        
///   <param term='custom'>
        
///       Array of parameters that are host application specific.
        
///   </param>
        
///   <seealso class='IDTExtensibility2' />
         public   void  OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode,  ref  System.Array custom)
        {
        }

        
///   <summary>
        
///       Implements the OnAddInsUpdate method of the IDTExtensibility2 interface.
        
///       Receives notification that the collection of Add-ins has changed.
        
///   </summary>
        
///   <param term='custom'>
        
///       Array of parameters that are host application specific.
        
///   </param>
        
///   <seealso class='IDTExtensibility2' />
         public   void  OnAddInsUpdate( ref  System.Array custom)
        {
        }

        
///   <summary>
        
///       Implements the OnStartupComplete method of the IDTExtensibility2 interface.
        
///       Receives notification that the host application has completed loading.
        
///   </summary>
        
///   <param term='custom'>
        
///       Array of parameters that are host application specific.
        
///   </param>
        
///   <seealso class='IDTExtensibility2' />
         public   void  OnStartupComplete( ref  System.Array custom)
        {
            CommandBars commandBars;
            CommandBar standardBar;
            commandBars 
=  applicationObject.CommandBars;

            
//  Get the standard CommandBar from Word
            standardBar  =  commandBars[ " Standard " ];

            
try
            {
                
//  try to reuse the button is hasn't already been deleted
                simpleButton  =  (CommandBarButton)standardBar.Controls[ " Excel COM Addin " ];
            }
            
catch  (System.Exception)
            {
                
//  If it's not there add a new button
                simpleButton  =  (CommandBarButton)standardBar.Controls.Add( 1 );
                simpleButton.Caption 
=   " Excel COM Addin " ;
                simpleButton.Style 
=  MsoButtonStyle.msoButtonCaption;
            }

            
//  Make sure the button is visible
            simpleButton.Visible  =   true ;
            simpleButton.Click 
+=   new  _CommandBarButtonEvents_ClickEventHandler(simpleButton_Click);

            standardBar 
=   null ;
            commandBars 
=   null ;
        }

        
///   <summary>
        
///       Implements the OnBeginShutdown method of the IDTExtensibility2 interface.
        
///       Receives notification that the host application is being unloaded.
        
///   </summary>
        
///   <param term='custom'>
        
///       Array of parameters that are host application specific.
        
///   </param>
        
///   <seealso class='IDTExtensibility2' />
         public   void  OnBeginShutdown( ref  System.Array custom)
        {
        }

        
void  simpleButton_Click(CommandBarButton ctrl,  ref   bool  cancelDefault)
        {
            MessageBox.Show(
" Welcome to COM Add In " );
        }
    }
}
 

声明了一个CommandBarButton的实例,然后将其添加到CommandBar中,并关联了一个Click事件,输出一则欢迎信息。

 

11、编译成功后,安装生成的setup.exe,执行安装:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

 

12、安装成功后,打开Excel,会在【Add-In】中发现我们新添加的按钮:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

 

六、调试COM加载项

1、通过前面的设置为Excel启动来进行调试,这也是首先的方法,很方便。

 

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

 

2、可以通过附加Excel进程的方式来进行调试:

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

 

 

七、小结

本次主要学习了COM 加载项的开发流程,对使用托管代码开发COM组件有了初步的认识,尤其是IDTExtensibility2接口,在VSTO开发中占据重要地位,理解其与COM交互的过程是很有必要的。其次是64位COM加载项的部署问题,与32位传统加载项有些区别,请注意区别对待。后续篇章会继续深入介绍VSTO开发的内容,及其与其他技术的整合。

 

你可能感兴趣的:(Office)