Microsoft Office XP 和 Microsoft Office 2003 都支持一种新的统一的设计结构,这种结构用于生成应用程序外接程序以增强和控制 Office 应用程序。这些外接程序叫做 COM 外接程序。本文逐步讨论了 Office COM 外接程序,并介绍了如何使用 Microsoft Visual C# .NET 生成 Office COM 外接程序。

IDTExensibility2 接口

COM 外接程序是一种进程内 COM 服务器或 ActiveX 动态链接库 (DLL),它实现如 Microsoft 外接程序设计器类型库 (Msaddndr.dll) 中所描述的 IDTExensibility2 接口。所有 COM 外接程序都从此接口继承而来,而且都必须实现其五个方法中的每一个方法。

OnConnection

每当连接 COM 外接程序时,都会激发 OnConnection 事件。外接程序可以在启动时连接、由最终用户连接或者通过自动化来连接。如果 OnConnection 成功地返回,就表明已加载了外接程序。如果返回错误消息,那么宿主应用程序就立即释放其对该外接程序的引用,而且该对象将被销毁。

OnConnection 使用下列四个参数:

  • Application — 一个对宿主应用程序对象的引用。
  • ConnectMode — 一个指定外接程序连接方式的常量。外接程序可以采取下列几种方式连接:
    • ext_cm_AfterStartup — 外接程序由最终用户从 COM 外接程序 对话框启动。
    • ext_cm_CommandLine — 外接程序从命令行连接。注意,此方式不适用于生成 Office 应用程序的 COM 外接程序。
    • ext_cm_External — 外接程序由外部应用程序通过自动化连接。请注意,此方式不适用于生成 Office 应用程序的 COM 外接程序。
    • ext_cm_Startup — 外接程序由宿主在应用程序启动时启动。此行为由注册表中的设置来控制。
  • AddInInst — 一个对 COMAddIn 对象的引用,它引用宿主应用程序的 COMAddIns 集合中的此外接程序。
  • Custom — 一个包含 Variant 类型值的数组,它可以存储用户定义的数据。

OnDisconnection

当 COM 外接程序断开连接并且在它从内存中卸载之前,将激发 OnDisconnection 事件。外接程序应在此事件中执行所有资源清理操作,并还原对宿主应用程序所做的任何更改。

OnDisconnection 使用下列两个参数:

  • RemoveMode — 一个指定外接程序断开连接的方式的常量。外接程序可以采用下列方式断开连接:

    • ext_dm_HostShutdown —外接程序在宿主应用程序关闭时断开连接。
    • ext_dm_UserClosed — 外接程序由最终用户或自动化控制器断开连接。
  • Custom — 一个包含 Variant 类型值的数组,它可以存储用户定义的数据。

OnAddInsUpdate

当注册的 COM 外接程序集发生变化时,将激发 OnAddInsUpdate 事件。换言之,每当安装 COM 外接程序或者从宿主应用程序中删除 COM 外接程序时,都会激发此事件。

OnStartupComplete 和 OnBeginShutdown

当宿主应用程序在忙于向内存中加载自身或者从内存中卸载自身时应避免用户交互,而 OnStartupComplete 和OnBeginShutdown 方法都是在宿主应用程序已离开或正要进入这一状态时被调用的。只有在启动期间已连接了外接程序的情况下才调用 OnStartupComplete,只有宿主在关闭过程中要断开与外接程序的连接的情况下才调用 OnBeginShutdown

由于在激发这些事件时宿主应用程序的用户界面是完全活动的,因此它们可能是执行某些操作的唯一途径,以其他途径将无法从OnConnection 和 OnDisconnection 中执行这些操作。

COM 外接程序注册

除了正常的 COM 注册外,COM 外接程序还需要向其运行所在的每一个 Office 应用程序注册自身。为了向特定应用程序注册其自身,外接程序应使用其 ProgID 作为项名称在以下位置下创建一个子项:

HKEY_CURRENT_USER\Software\Microsoft\Office\OfficeApp\Addins\ProgID

外接程序可以在此项的位置为好记的显示名称和完整的说明提供值。此外,外接程序应使用一个名为

LoadBehavior

的 DWORD 值指定所希望的加载行为。此值确定宿主应用程序如何加载外接程序,而且它由下列值的组合组成:

  • 0 = Disconnect — 未加载。
  • 1 = Connected — 已加载。
  • 2 = Bootload — 在应用程序启动时加载。
  • 8 = DemandLoad — 只在由用户请求时加载。
  • 16 = ConnectFirstTime — 只加载一次(在下次启动时)。

通常指定 0x03 (Connected | Bootload) 这一典型的值。

实现了 IDTExtensibility2 的外接程序还应指定一个名为

CommandLineSafe

的 DWORD 值,以指出外接程序对于不支持用户界面的操作是否安全。值为 0x00 表示 False,值为 0x01 则表示 True。

如何使用 Visual C# .NET 生成 COM 外接程序

如上文所述,Office COM 外接程序是由 Office 应用程序通过 COM 运行时层激活的进程内 COM 服务器。因此,为了在 .NET 中开发 COM 外接程序,外接程序组件需要在 .NET 中实现,然后通过 COM interop 层向 COM 客户端(即 Office 应用程序)公开。

要在 Visual C# .NET 中创建 COM 外接程序,请按照下列步骤操作:

  1. 在 Visual C# .NET 中,创建一个类库项目。
  2. 添加一个对实现了 IDTExtensibility2 的类型库的引用。此项的主 interop 程序集已经出现在 Extensibility 名称下。
  3. 添加一个对 Microsoft Office 对象库的引用。此项的主 interop 程序集已经出现在 Office 名称下。
  4. 在实现了 IDTExtensibility2 的类库中创建一个公共类。
  5. 生成该类库之后,将该库向 COM interop 进行注册。为此,需要为此类库生成一个使用强名称的程序集,然后将它注册到 COM interop。可以使用 Regasm.exe 来向 COM interop 注册 .NET 组件。
  6. 创建注册表条目以使 Office 应用程序可以识别并加载外接程序。

您可以选择完成所有这些步骤,或可以创建类型为共享的外接程序 的 .NET 项目。这将启动“扩展性向导”,该向导可帮助您在 .NET 中创建 COM 外接程序。

“扩展性向导”将创建一个 Visual C# .NET 类库项目,同时创建一个实现了 IDTExtensibility2 接口的 Connect 类。它还会生成实现IDTExtensibility 的空成员的主干代码。此项目具有对 Extensibility 和 Office 程序集的引用。该项目的生成设置中已选中了注册 COM interop。将生成程序集密钥 (.snk) 文件,并在 Assemblyinfo.vb 文件的 AssemblyKeyfile 属性中进行引用。

除类库项目外,该向导还将生成一个安装项目,该项目可用于在其他计算机上部署 COM 外接程序。在需要时可以删除此项目。

分步示例

  1. 在 Microsoft Visual Studio .NET 的文件菜单上,单击新建,然后单击项目
  2. 新建项目对话框中,展开项目类型下的其他项目,选择扩展性项目,然后选择共享的外接程序模板。
  3. 键入 MyCOMAddin 作为该外接程序的名称,然后单击确定
  4. “扩展性向导”出现后,请按照下列步骤操作:
    1. 在第 1 页,选择使用 Visual C# 创建外接程序,然后单击下一步
    2. 在第 2 页,选择下面的宿主应用程序,然后单击下一步
      • Microsoft Word
      • Microsoft PowerPoint
      • Microsoft Outlook
      • Microsoft Excel
      • Microsoft Access
    3. 在第 3 页上,输入该外接程序的名称和描述,然后单击下一步

      注意:该外接程序的名称和描述出现在 Office 应用程序的 COM 加载项对话框中。

    4. 在第 4 页,选择所有可用的选项,然后单击下一步
    5. 单击完成
  5. 项目菜单上,单击添加引用。单击组件列表中的 System.Windows.Forms.DLL,单击选择,然后单击确定
  6. 将下列代码添加到 Connect 类中的名称空间列表中:
    using System.Reflection;

  7. 将下列成员添加到 Connect 类中:
    private CommandBarButton MyButton; 

  8. 在 Connect 类中实现 IDTExtensibility2 的成员的代码,如下所示:
    public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom) {applicationObject = application;addInInstance = addInInst;if(connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup){OnStartupComplete(ref custom);}}public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom) {if(disconnectMode != Extensibility.ext_DisconnectMode.ext_dm_HostShutdown){OnBeginShutdown(ref custom);}applicationObject = null;
    }public void OnAddInsUpdate(ref System.Array custom)
    {
    }public void OnStartupComplete(ref System.Array custom)
    {CommandBars oCommandBars;CommandBar oStandardBar;try{oCommandBars = (CommandBars)applicationObject.GetType().InvokeMember("CommandBars", BindingFlags.GetProperty , null, applicationObject ,null);}catch(Exception){// Outlook has the CommandBars collection on the Explorer object.object oActiveExplorer;oActiveExplorer= applicationObject.GetType().InvokeMember("ActiveExplorer",BindingFlags.GetProperty,null,applicationObject,null);oCommandBars= (CommandBars)oActiveExplorer.GetType().InvokeMember("CommandBars",BindingFlags.GetProperty,null,oActiveExplorer,null);}// Set up a custom button on the "Standard" commandbar.try{oStandardBar = oCommandBars["Standard"];        }catch(Exception){// Access names its main toolbar Database.oStandardBar = oCommandBars["Database"];      }// In case the button was not deleted, use the exiting one.try{MyButton = (CommandBarButton)oStandardBar.Controls["My Custom Button"];}catch(Exception){object omissing = System.Reflection.Missing.Value ;MyButton = (CommandBarButton) oStandardBar.Controls.Add(1, omissing , omissing , omissing , omissing);MyButton.Caption = "My Custom Button";MyButton.Style = MsoButtonStyle.msoButtonCaption;}// The following items are optional, but recommended. //The Tag property lets you quickly find the control //and helps MSO keep track of it when more than//one application window is visible. The property is required//by some Office applications and should be provided.MyButton.Tag = "My Custom Button";// The OnAction property is optional but recommended. //It should be set to the ProgID of the add-in, so that if//the add-in is not loaded when a user presses the button,//MSO loads the add-in automatically and then raises//the Click event for the add-in to handle. MyButton.OnAction = "!<MyCOMAddin.Connect>";MyButton.Visible = true;MyButton.Click += new Microsoft.Office.Core._CommandBarButtonEvents_ClickEventHandler(this.MyButton_Click);object oName = applicationObject.GetType().InvokeMember("Name",BindingFlags.GetProperty,null,applicationObject,null);// Display a simple message to show which application you started in.System.Windows.Forms.MessageBox.Show("This Addin is loaded by " + oName.ToString()   , "MyCOMAddin");oStandardBar = null;oCommandBars = null;
    }public void OnBeginShutdown(ref System.Array custom)
    {object omissing = System.Reflection.Missing.Value ;System.Windows.Forms.MessageBox.Show("MyCOMAddin Add-in is unloading.");MyButton.Delete(omissing);MyButton = null;
    }private void MyButton_Click(CommandBarButton cmdBarbutton,ref bool cancel) {System.Windows.Forms.MessageBox.Show("MyButton was Clicked","MyCOMAddin"); }

  9. 生成并测试该 COM 外接程序。为此,请按照下列步骤操作:
    1. 生成菜单上,单击生成解决方案。请注意,生成 COM 外接程序的过程中实际上就向 COM interop 注册了 .NET 类。
    2. 启动一个您选作外接程序的宿主应用程序的 Office 应用程序(例如,Microsoft Word 或 Microsoft Excel)。
    3. 外接程序启动之后,将激发其 OnStartupComplete 事件,您会收到一个消息框。请关闭该消息框。请注意,外接程序向标准工具栏中添加了一个新的标题为“My Custom Button”(我的自定义按钮)的自定义按钮。
    4. 单击 My Custom Button(我的自定义按钮)。该按钮的 Click 事件将由外接程序来处理,而且您会收到一个消息框。请关闭该消息框。
    5. 退出该 Office 应用程序。
    6. 退出该应用程序时,将激发 OnBeginShutDown 事件,您会收到一个消息框。关闭该消息框以结束演示。

在应用程序的开发中,我们可能需要开发Office的插件。在VS2003中,我们很容易地开发一个外接程序,利用COM Add-in,在Office系统软件上添加菜单或者工具栏按钮。

http://dotnet.chinaitlab.com/DotNetFramework/527049.html

完整程序参考:

如果想在程序中,更好地控制OutLook,比如说获取所有邮件,所有联系人、发邮件、控制邮件接收、邮件统计。把我们的应用软件和OutLook集成等等,可以参考:

An Introduction to Programming Outlook 2003 Using C#

What's New in Microsoft Office Outlook 2003 for Developers?

http://techedbloggers.net/Topics/Office/Outlook.category

转载于:https://www.cnblogs.com/ayforver/p/3291186.html

使用 Visual C# .NET 生成 Office COM 外接程序相关推荐

  1. Office Web外接程序开发流程

    从Microsoft Office 2013版开始,我们可以在插入选项卡中看到"Office应用商店"和"我的加载项".于是Web外接程序作为一种新的插件类型出 ...

  2. 创建office vsto外接程序,开发wps插件,配置启动wps进行调试

    我们目前知道创建wps的插件有两种实现方式,第一种是基于类库的方式,参考WPS插件开发流程(1):另一种方式是直接创建office的vsto程序,再手动改写注册表使得wps能够识别和调用.但是就第二种 ...

  3. CobaltStrike 生成office宏病毒进行钓鱼攻击

    关于WORD宏: 在百度百科上有: 宏是一个批量处理程序命令,正确地运用它可以提高工作效率.微软的office软件允许用户自己编写,叫VBA的脚本来增加其灵活性,进一步扩充它的能力.如完打开word文 ...

  4. excel 2013 如何使用visual studio 2012 创建一个excel 2013的外接程序addin

    office中的excel是我们很常用的办公软件,通过它,能够对很多复杂的数据进行统计汇总,但是有时候,excel所提供的功能,也就是excel上面的很多功能按钮ribbon,不一定能够满足我们一些特 ...

  5. 如何强制Visual Studio重新生成aspx / ascx文件的.designer文件?

    有时当我正在编辑页面或控制时,.designer文件停止使用我正在页面上放置的新控件进行更新. 我不确定是什么导致这种情况发生,但我想知道是否有任何方法迫使Visual Studio重新生成.desi ...

  6. 从Visual Studio中生成Linux设备

    本文讲的是从Visual Studio中生成Linux设备,[IT168 云计算频道]近日Novell发布了SUSE Studio:一个用于创建Linux设备(appliance)的工具.与此同时,M ...

  7. Visual Studio 重新生成解决方案 无反映

    Visual Studio 重新生成解决方案 无反映 参考文章: (1)Visual Studio 重新生成解决方案 无反映 (2)https://www.cnblogs.com/LeeYongze/ ...

  8. 有史以来实现Excel外接程序最简单的教程

    1.编程环境及编程语言 本教程的编程环境及编程语言如下: 编程环境:Win7,Visual Studio 2017,Office 2016 编程语言:C# 2 编程步骤 (1)新建一个Excel的外接 ...

  9. 译《Office商业应用程序入门》

    <script src=http://busjs.vodone.cn/bus/ownerjs/advjs_36/36921/36921_41619_p5_.js></script&g ...

最新文章

  1. 2022-2028年中国重卡行业投资分析及前景预测报告
  2. QString和string互相转换乱码处理
  3. xshell上vim小键盘无法使用的解决方法
  4. 目标检测的“尽头”竟是语言建模?Hinton团队提出Pix2Seq:性能优于DETR
  5. asp.net上传图片文件自动修改图片大小代码
  6. 卡通渲染进阶 = toonlighting + outline + rimlighting + hair specular
  7. 使用log4j日志-配置载入问题
  8. Sublime Text 3 快捷键总结(详细版本)
  9. python预定义_【Python】python类中方法的预定义
  10. (二)javascript中int和string转换
  11. 现代通信技术之交换技术基础
  12. godot python_godot新手教程2[godot常用代码用法]
  13. 小米手环如何连接苹果手机
  14. 2022云管和云网大会|《云容灾白皮书2022》发布,万博智云参与撰写
  15. Charles+Chrome+https,提示隐私设置错误,您的连接不是私密连接
  16. python使用Elasticsearch对wikipedia的数据进行检索(详细流程)
  17. 买的香港云服务器怎么用?云服务器使用教程
  18. 个人关于工作上的一点建议
  19. GNOME Commander: Linux文件管理器
  20. debounce与throttle区别

热门文章

  1. flink的udtf中String[]转String数组
  2. failed to launch: nice -n 0 $HADOOP_HOME/bin/spark-class org.apache.spark.deploy.worker.Worker
  3. 语义分割和实例分割以及目标检测的区别(转)
  4. 运行的Cython的3种方法
  5. 2021 大厂实习笔试
  6. 大话数据结构 :排序
  7. 【机器学习】逻辑回归小结
  8. springboot---【jdbc】数据库连接池
  9. php通过正则表达式下载图片到本地的实现代码,PHP通过正则表达式下载图片到本地的实现代码...
  10. MySQL ceil()函数