zoukankan      html  css  js  c++  java
  • VSTO:使用C#开发Excel、Word【6】

    Office主互操作程序集(PIA)
    在了解如何构建Office解决方案之前,您需要更详细地了解在.NET中与Office对象模型通信的托管程序集。用于与Office通话的托管程序集称为Office主互操作程序集(PIA)。

    如前所述,当您正在与.NET中的Office对象模型交谈时,您可以通过称为COM互操作的.NET技术与之交谈。 Office对象模型全部以公开COM接口的非托管代码(C和C ++)编写。要通过托管代码(C#或Visual Basic)与这些COM接口通话,您可以通过一个包装器进行通话,允许托管代码与Office的非托管COM接口进行交互操作。这个包装器是一组被编译成一个称为主互操作程序集或PIA的程序集的.NET类。

    描述这些程序集时使用“primary”一词,因为它们是经Office认可的用于与Office对象模型通信的包装器。需要这个指定,因为您可以使用.NET提供的工具(称为TLBIMP)为Office COM对象模型创建自己的包装器。您自己创建的包装器称为互操作程序集(IA),而不是主互操作程序集。即使您可能会尝试使用TLBIMP并构建自己的互操作程序集,但除了Office提供的互操作程序集之外,您也不应该使用任何其他操作来进行Office开发。如果每个开发人员都为自己的Office开发人员创建了自己的套装,那么没有Office解决方案可以与任何人的解决方案进行互操作;每个interop包装类,例如每个开发人员创建的Worksheet将被视为一种不同的类型。即使我创建的Interop程序集有一个Worksheet对象,并且您创建的Interop程序集具有一个Worksheet对象,我无法传递我的Worksheet对象,也不能传递给您的Worksheet对象。我们需要使用相同的互操作程序集:主互操作程序集。

    不建立自己的互操作程序集的第二个原因是Office已经对PIA进行了特殊修复,以便在执行Office开发时使它们更好地工作。如果您生成自己的,那么您很可能遇到在PIA中修复的问题。

    安装PIA
    Office 2003 PIA可通过Office 2003安装程序获得。 Office 2003 PIA也可以作为Microsoft Windows Installer包提供,您可以使用应用程序重新分发。要通过Office 2003安装程序安装Office 2003 PIA,进行安装时,请在Office 2003安装向导的第一步中选中“选择应用程序高级自定义”复选框。然后在向导的下一个屏幕中显示的树控件中,您将在每个应用程序下面看到一个可编程控制器可用的.NET可编程性支持节点,如图1-4所示。单击每个这些.NET可编程支持节点,并确保您从我的计算机设置运行。此外,在树中的Office工具节点下,您可能需要启用Microsoft Forms 2.0 .NET可编程支持和智能标记.NET可编程性支持。获取Office 2003 PIA的第二种方法是完成Office 2003all的安装,.NET可编程性支持将自动打开。

    Office PIA安装到全局程序集缓存(GAC)。 GAC通常位于Windows目录的Assembly子目录中。

    有多个Office PIA可用。 表1-4列出了最常见的一些。 这里列出的一个PIA是Office.dll PIA,它是在Office应用程序(如CommandBar)之间共享的常见类型。

    参考PIAs
    添加对PIA的引用对于大多数VSTO项目是不必要的,因为引用将自动为您添加。 本书中的控制台应用程序示例,例如自动化Excel的控制台应用程序示例可以键入Visual Studio控制台项目并编译,但必须先添加对必要的PIA的引用。 要添加引用,请在Visual Studio解决方案资源管理器中右键单击项目下的“引用”文件夹,如图1-5所示。 在右键单击“引用”文件夹时,从弹出的菜单中选择“添加引用”。

    选择出现的“添加引用”对话框的COM选项卡,如图1-6所示。 COM引用按组件名称列出,与表1-4中的描述列匹配。 因此,要添加对Excel PIA的引用,请选择Microsoft Excel 11.0对象库,然后单击确定按钮将Excel 2003 PIA参考添加到项目中,如图1-6所示。

    请注意图1-6中“添加引用”对话框的“COM”选项卡中的“路径”列显示PIA包装的COM库的路径。例如,Microsoft Excel 11.0 Object Library指向您的计算机上Excel.EXE可执行文件的位置。当您选择这些引用并关闭对话框时,可以通过扩展项目中的“引用”文件夹,右键单击添加的引用,然后选择“属性”,来检查添加的实际引用的属性。您将看到Visual Studio计算出GAC中与您选择的COM对象相对应的PIA托管对象。在这种情况下,您将不会获得对Excel.EXE可执行文件的引用,而是GAC中的Microsoft.Office.Interop.Excel.dll。

    最后,请注意,即使您没有明确添加对Microsoft Office 11.0 Object Library(office.dll)的引用,也为您添加了一个引用。这是因为Excel 11.0 Object Library使用Microsoft Office 11.0 Object Library中的类型。 Visual Studio检测到这一点,并自动将所需的Office PIA添加到您的项目引用。

    浏览PIA
    当您看到在Visual Studio中的对象浏览器中引用的PIA时,您可能会发现自己很困惑。对象浏览器显示了作为互操作包装器一部分创建的许多辅助对象。例如,考虑.NET Interop对于看似简单的Excel Application对象的引用。它变成一个多关联的头部引用(8个头标准引用,36私自引用)。以下所有以下是在浏览器中与Excel Application对象相关的公共类型:

    Interfaces(接口

    • _Application

    • AppEvents

    • AppEvents_Event

    • Application

    • IAppEvents

    Delegates(委托)

    • AppEvents_*EventHandler (29 of them)

    Classes(类)

    • AppEvents_SinkHelper (AppEvents)

    • ApplicationClass (_Application, Application, AppEvents_Event)

    此图形针对Chart,OLEObject,QueryTable,Worksheet和Workbook。

    我们尝试通过从Excel Application对象的原始COM定义向后工作来解开这个混乱。 Application对象的COM coclass看起来像thisit有两个接口,一个称为_Application的主接口和一个名为AppEvents的事件接口。 您可以将coclass视为定义COM类实现的接口的东西。

    coclass Application {
            [default] interface _Application;
            [default, source] dispinterface AppEvents;
        };

    TLBIMP(用于处理Excel的COM类型库并使用PIA)直接导入_Application和AppEvents接口,因此这解释了八种类型中的两种来自哪里。但是AppEvents界面不是很有用,似乎像某种TLBIMP转换的工件。它必须进一步处理,以创建后面描述的AppEvents_Event的另一个界面。

    当TLBIMP处理COM coclass时,它将创建一个名为ApplicationClass的.NET类,它通过获取coclass名称并附加Class命名。它还创建一个与名为Application的coclass同名的.NET接口。如果您在浏览器中查看应用程序,它没有属于自己的属性和方法,但它来自与coclass相关联的其他两个接口:_Application和AppEvents_Event。

    我们还没有解释AppEvents_Event接口来自哪里。当TLBIMP处理coclass上的AppEvents事件接口时,它会创建几个帮助类型。首先,它创建AppEvents_Event,它看起来像AppEvents,但事件和委托类型替换AppEvents中的方法。它还创建名为AppEvents_ * EventHandler的代理,其中*是原始AppEvents界面上每个方法的方法名称。最后,它创建一个可以忽略的AppEvents_SinkHelper。

    这只会使IAppEvents界面无法解释。 TLBIMP直接导入此接口,因为它是Excel类型库中的公共类型。你也可以忽略这个。这实际上是AppEvents的重复,除了AppEvents在类型库中声明为dispinterface,而IAppEvents被声明为双重接口类型。

    那么你真的使用哪些?基本上,你应该只在代码中使用Application接口(派生自_Application和AppEvents_Events)和代理。你通常可以假装别人不存在。此规则的一个例外是当方法和事件名称相冲突,如本章前面所述。要在要连接到事件时要调用该方法或AppEvents_Event接口的方法和事件之间消除歧义,则必须将其转换为_Application接口。表1-5给出了一个总结。

    由TLBIMP为coclass创建的应用程序接口以有趣的方式表现。 您可以在C#中编写代码,使其看起来像您正在创建应用程序界面的一个实例,我们都知道这是不可能的:

    Excel.Application myApp = new Excel.Application();

    真的,这是在幕后使用ApplicationClass的语法糖(应用程序界面归因于将其与ApplicationClass相关联)来创建一个Excel Application对象并返回相应的接口。

    最后,我们前面提到这个模式对于Chart,OLEObject,QueryTable,Worksheet和Workbook都是重复的。 图表映射是带ChartEvents的图表和AppEvent的直接应用程序,您将得到一般的想法。 工作表有点不同 它的coclass看起来像这样:

    coclass Worksheet {
            [default] interface _Worksheet;
            [default, source] dispinterface DocEvents;
        };

    所以对于工作表,使用Worksheet替换Application,而是将AppEvents替换为DocEventsyielding DocEvents_ * EventHandler作为WorkSheet事件的代理。

    QueryTable甚至是极限。 它的coclass看起来像这样:

    coclass QueryTable {
            [default] dispinterface _QueryTable;
            [default, source] dispinterface RefreshEvents;
        };

    所以对于QueryTable,使用QueryTable替换Application,并将AppEvents替换为Refresh Event,从而生成RefreshMents * EventHandler作为QueryTable事件的委托。

    Dummy方法

    当您在Visual Studio中的对象浏览器中查看Excel PIA时,您可能会注意到其中包含文本Dummy的大量方法。甚至有一个名为IDummy的界面。

    不,这不是Excel的侮辱你的智慧的方式。一切都是虚拟的,它是一种测试方法,在Microsoft的内部“调试”版本中实际上具有合法目的和更具描述性的名称。例如,Application.Dummy6在Excel的调试版本中称为Application.DebugMemory。在Excel的零售版本中,每种方法都重命名为Dummy。这些Dummy方法中的所有508实际上都在调试Excel中做了一些事情,但是在零售版本的Excel中,除了在调用时引发错误,它们什么都不做。

    Excel将这些标记为“隐藏”,但C#对象浏览器默认显示隐藏方法。当您在C#对象浏览器中查看PIA时,您将看到这些Dummy方法。如果创建Visual Basic项目,Visual Basic对象浏览器将隐藏具有此属性的方法和属性。

    结论
    本章介绍了Office对象模型,并研究了对象模型的基本结构。 您学习了如何使用对象,集合和枚举在任何对象模型中找到的基本类型。 您还学习了如何使用Office对象模型中的对象和集合公开的属性,方法和事件。

    本章介绍了将Office对象模型暴露给.NET代码的Office主互操作程序集。 您学习了如何在Visual Studio项目中使用和引用Office PIA。 本章还介绍了在对象浏览器中查看PIA时可以忽略的内容。

    下一章将开始研究Office编程中使用的基本开发模式,并提供各种示例。

  • 相关阅读:
    yii2 gii 命令行自动生成控制器和模型
    控制器中的方法命名规范
    Vue Property or method "" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based
    IDEA插件:GsonFormat
    Spring Boot : Access denied for user ''@'localhost' (using password: NO)
    Typora添加主题
    Git基础命令图解
    Java Joda-Time 处理时间工具类(JDK1.7以上)
    Java日期工具类(基于JDK1.7版本)
    Oracle SQL Developer 连接Oracle出现【 状态: 失败 -测试失败: ORA-01017: invalid username/password; logon denied】
  • 原文地址:https://www.cnblogs.com/xiehaofeng/p/7497300.html
Copyright © 2011-2022 走看看