[转]创建一个 Microsoft Outlook 扩展插件
本文转自:https://coyee.com/article/10625-how-to-create-an-add-in-for-microsoft-outlook
1.介绍
Visual Studio Tool for Office(VSTO)加载项是.NET Framework中提供的工具集,可让我们在(版本2003及更高版本)中扩展和自定义Microsoft Office产品。
在本教程中,我们将使用Outlook 2013作为案例研究和Visual Studio 2015。
2.Outlook对象模型
这是当您想创建Outlook加载项时的起点,了解这些对象的含义很重要。
Outlook对象模型:
- Application:它代表Outlook应用程序,是模型中最高级别的对象。该对象是到达模型的其他对象的起点。
 - Explorer:它表示一个窗口来显示文件夹的内容,如电子邮件,消息,任务,约会等。
 - Inspector:它表示一个显示项目的窗口,如电子邮件消息,任务,约会等。
 - MAPIFolder:它代表一个包含电子邮件,联系人,约会等的文件夹。备注:此对象已过时,替代地,您应该使用MAPIFolder的Folder 对象实例。
 - MailItem:它代表一封电子邮件。
 - AppointmentItem:它代表会议,一次性约会,日程预约或日历 文件夹中的会议。
 - TaskItem:它表示在指定时间范围内执行的任务。
 - ContactItem:它表示Contact文件夹中的联系人。
 
3. 如何开始
在下一节中,我们将从这种类型的应用开始讲解。
3.1. 如何创建项目
- 启动Visual Studio。
 - 文件菜单 / 新建/ 项目。
 - 在项目的模型面板中,打开Visual C#,Office/SharePoint,Office 加载项。
 - 选择Outlook 2013 和 2016 VSTO 加载项加入模型。
 - 填写项目名称,然后单击OK。
 
3.2. 项目布局
实际上,为Visual Studio生成的项目布局是非常直观和简单的。

主类是 ThisAddIn ,代码如下所示:
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
} private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
// Note: Outlook no longer raises this event. If you have code that
// must run when Outlook shuts down, see
// http://go.microsoft.com/fwlink/?LinkId=506785
} #region VSTO generated code /// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
} #endregion
}
这是一个非常简单的类。 ThisAddIn_Startup方法是应用程序的起始点。 在这个方法中,我们可以得到对象Application和模型的其他对象。 此外,我们可以执行我们的初始化过程,如配置和访问数据库。
当用户关闭Outlook时执行ThisAddIn_Shutdown方法。 但重要的是,在Outlook当前版本中,由于性能问题,此方法没有被调用。 但是,如果在Outlook关闭时需要执行某些代码,则可以检查此链接以获取其他选项。
3.3. 应用程序对象和其他模型对象
接下来,我们将会看到如何获得一些对象模型。因此,我们需要使用必要的命名空间:
using Outlook = Microsoft.Office.Interop.Outlook;
代码如下所示:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
// Get the Application object
Outlook.Application application = this.Application; // Get the Inspector object
Outlook.Inspectors inspectors = application.Inspectors; // Get the active Inspector object
Outlook.Inspector activeInspector = application.ActiveInspector();
if (activeInspector != null)
{
// Get the title of the active item when the Outlook start.
MessageBox.Show("Active inspector: " + activeInspector.Caption);
} // Get the Explorer objects
Outlook.Explorers explorers = application.Explorers; // Get the active Explorer object
Outlook.Explorer activeExplorer = application.ActiveExplorer();
if (activeExplorer != null)
{
// Get the title of the active folder when the Outlook start.
MessageBox.Show("Active explorer: " + activeExplorer.Caption);
}
}
其他对象模型可以通过使用 Inspector 和 Explorer 对象来获取。该操作通常基于事件,因此,需要注册这两个对象创建的事件。代码大概是这样的:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
// ...
// Add a new Inspector to the application
inspectors.NewInspector +=
new Outlook.InspectorsEvents_NewInspectorEventHandler(
Inspectors_AddTextToNewMail);
}
Inspectors_AddTextToNewMail 是实现我们功能的方法,如下所示:
void Inspectors_AddTextToNewMail(Outlook.Inspector inspector)
{
}
inspector参数应当是对电子邮件或联系人的引用,具体取决于Outlook中的用户操作。
3.4.在项目结束
在项目结束时,要从开发计算机上的Outlook中删除加载项,请转到Visual Studio中的生成(Build )菜单,然后单击清除解决方案(Clean Solution)选项。
3.5.如何制作安装程序
在Visual Studio中,转到Build菜单/“Publish ...”。
备注:有时Visual Studio生成的安装程序可能会在安装在用户计算机中时失败,您应该会收到以下错误消息:
引用:
“不能解析属性为'类型'的值。错误:无法加载文件或程序集…“。
4. 基本示例
在下一节中,我们将展示一些关于如何为Outlook 2013创建VSTO加载项的示例。
4.1. 如何处理新的电子邮件
下面的示例是,用户创建一封新的电子邮件时,我们会在邮件的主题和正文中插入自定义文本。为了完成这个任务,我们需要在ThisAddIn_Startup方法中注册一个新的 Inspector ,当用户创建或者打开邮件的时候,就会触发调用Inspectors_AddTextToNewMail方法。
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
// Get the Application object
Outlook.Application application = this.Application; // Add a new Inspector
inspectors.NewInspector +=
new Outlook.InspectorsEvents_NewInspectorEventHandler(
Inspectors_AddTextToNewMail);
} void Inspectors_AddTextToNewMail(Outlook.Inspector inspector)
{
// Get the current item for this Inspecto object and check if is type
// of MailItem
Outlook.MailItem mailItem = inspector.CurrentItem as Outlook.MailItem;
if (mailItem != null)
{
if (mailItem.EntryID == null)
{
mailItem.Subject = "My subject text";
mailItem.Body = "My body text";
}
}
}
注意: 需要检查 mailItem 对象是否是一种 MailItem 类,因为当这个事件被触发时,通过  Outlook 的用户操作,我们并不知道哪个Inspector对象会被执行。
4.2. 如何处理一封在发送的邮件
下面的示例是,在电子邮件发送时,允许我们更新邮件里的消息。这是一个非常有趣和适用的功能。有一些Outlook加载项可以执行这种类型的操作,例如,防病毒软件需要在邮件被发送时包含签名。
为了完成这些功能,我们将会在 ItemSend 事件中插入我们的代码。当一个邮件通过用户或者计划任务被发送时,这个事件就会被触发。
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
// Get the Application object
Outlook.Application application = this.Application; // Subscribe to the ItemSend event, that it's triggered when an email is sent
application.ItemSend +=
new Outlook.ApplicationEvents_11_ItemSendEventHandler(
ItemSend_BeforeSend);
} void ItemSend_BeforeSend(object item, ref bool cancel)
{
Outlook.MailItem mailItem = (Outlook.MailItem) item;
if (mailItem != null)
{
mailItem.Body += "Modified by GettingStartedOutlookAddIn";
}
cancel = false;
}
4.3.如何将控件添加到功能区工具栏
在下面的示例中,我们将看到如何在Outlook中的功能区(工具栏)中添加控件。 具体来说,当用户编辑或读取电子邮件时,如何添加按钮到功能区。
执行以下操作:
- 向项目添加一个新项目。 在本例中,我命名为RibbonDemo。

 - 在功能区设计器中,选择功能区组件并转到属性窗口。
 - 查找RibbonType属性并选择Microsoft.Outlook.Mail.Compose和Microsoft.Outlook.Mail.Read的值,它指的是创建和读取电子邮件的功能区。
 - 我们为组设置一个合适的名称。 为了完成它,选择它并在属性窗口中查找Label属性并为其键入名称。
 

- 接下来,我们从ToolBox中添加按钮并准备好。
 - 或者,使用按钮的ControlSize和ShowImage属性,我们可以完成Microsoft Office产品的外观。
 

接下来就像开发 C# 桌面应用程序一样,让我们编写 ButtonDemo按钮的OnClick事件来处理邮件消息。
private void buttonDemo_Click(object sender, RibbonControlEventArgs e)
{
// Get the Application object
Outlook.Application application = Globals.ThisAddIn.Application; // Get the active Inspector object and check if is type of MailItem
Outlook.Inspector inspector = application.ActiveInspector();
Outlook.MailItem mailItem = inspector.CurrentItem as Outlook.MailItem;
if (mailItem != null)
{
MessageBox.Show("Subject: " + mailItem.Subject);
}
}
5.其他对象模型的例子
在下面的部分中,我们将看到需要访问其他对象模型的示例。
将我们的内容放置在上下文中,当我们使用电子邮件正文时,我们可以使用Outlook对象执行一些功能,例如访问MailItem对象的Body属性。 但是,如果需要更多地控制电子邮件正文,则需要将其作为Word文档。 接下来,我们将会看到一些例子。
开始之前
首先,我们将看到如何从“Outlook 2013和2016 VSTO加载项”中引用Word对象模型。 选择您在Outlook应用程序中使用的相同版本以及选择工具和实用程序的引用非常重要。
在我的案例中,我使用的是15.0.0.0 版本的Outlook。

因此,我们将选择相同版本的 Word 引用。

5.1. 如何通过 Ribbon 上的按钮获取电子邮件里选中的文本。
下面的示例是,一个含OnClick 事件的按钮添加到Ribbon(参见前面的章节 4.3. 如何添加一个控件到 Ribbon 工具栏)。
private void button2Demo_Click(object sender, RibbonControlEventArgs e)
{
// Get the Application object
Outlook.Application application = Globals.ThisAddIn.Application; // Get the active Inspector object and check if is type of MailItem
Outlook.Inspector inspector = application.ActiveInspector();
Outlook.MailItem mailItem = inspector.CurrentItem as Outlook.MailItem;
if (mailItem != null)
{
Word.Document document = (Word.Document) inspector.WordEditor;
string selectedText = document.Application.Selection.Text;
MessageBox.Show(selectedText);
}
}
当用户创建新的电子邮件时,会出现以下图片。 在这里,我们可以看到应用程序显示一条消息,其中包含用户已选择并单击“获取文本选择”按钮的文本。

5.2. 如何订阅电子邮件正文的事件
在下面的示例中,我们将演示如何将我们的应用程序订阅到用户通过电子邮件正文执行的事件。 具体来说,我们将订阅Word文档中的事件(它代表电子邮件正文),当用户对文本进行双击时,我们将获得点击完成时的单词。
我们将从应用程序入口点开始,我们将创建一个Inspector对象来监视用户何时创建/编辑电子邮件。
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
// Get the Application object
Outlook.Application application = this.Application; // Add a new Inspector
inspectors.NewInspector +=
new Outlook.InspectorsEvents_NewInspectorEventHandler(
Inspectors_RegisterEventWordDocument);
}
使用这个Inspector,我们在打开电子邮件编辑器时执行我们的代码。 此时,我们将检查Inspector对象是否为MailItem。 接下来,我们将检查电子邮件编辑器是否是Word编辑器(有时是另一种类型),最后我们将获取Word文档对象。
void Inspectors_RegisterEventWordDocument(Outlook.Inspector inspector)
{
Outlook.MailItem mailItem = inspector.CurrentItem as Outlook.MailItem;
if (mailItem != null)
{
// Check that the email editor is Word editor
// Although "always" is a Word editor in Outlook 2013, it's best done perform this check
if (inspector.EditorType == Outlook.OlEditorType.olEditorWord
&& inspector.IsWordMail())
{
// Get the Word document
Word.Document document = inspector.WordEditor;
if (document != null)
{
// Subscribe to the BeforeDoubleClick event of the Word document
document.Application.WindowBeforeDoubleClick +=
new Word.ApplicationEvents4_WindowBeforeDoubleClickEventHandler(
ApplicationOnWindowBeforeDoubleClick);
}
}
}
}
接下来,我们将订阅我们得到的Word文档的BeforeDoubleClick事件(在以前的代码中),当触发事件时,我们将选择用户点击的单词。
private void ApplicationOnWindowBeforeDoubleClick(Word.Selection selection,
ref bool cancel)
{
// Get the selected word
Word.Words words = selection.Words;
MessageBox.Show("Selection: " + words.First.Text);
}
我们可以通过“选择(selection)”对象访问用户选择的单词,它具有很多功能。 在我们的示例中,使用Word属性,我们得到用户所有选定单词的集合,第一个属性是用户点击的位置。
当用户创建新的电子邮件时,会出现以下图片。 在这里,我们可以看到应用程序显示一个消息,其中包含用户双击的文本。

6.结论
可以看出,使用VSTO加载项工具,我们可以通过多种方式轻松扩展Outlook功能。 在我看来,企业部门的这种应用有很多要求,可以快速解决某些问题,比起其他应用程序,通常办公室用户对微软Office产品感到更满意。 使用VSTO加载项,我们可以查询数据库以获取员工的联系人,将产品列表包含在电子邮件中,同步企业应用程序与Outlook之间的约会等等。
7.参考文献
[转]创建一个 Microsoft Outlook 扩展插件的更多相关文章
- 如何创建一个Edge 浏览器扩展
		
随着微软Windows 10 年度更新的发布,数次延宕的Edge 扩展功能终于得到了官方正式支持.我在我的另外一个博客上发布了如何创建一个Edge 浏览器扩展的博文,链接如下: https://blo ...
 - 小教程:自己创建一个jQuery长阴影插件
		
长阴影设计是平面设计的一个变体,添加了阴影,产生了深度的幻觉,并导致了三维的设计.在本教程中,我们将创建一个jQuery插件,通过添加完全可自定义的长阴影图标,我们可以轻松地转换平面图标. 戳我查看效 ...
 - 如何创建一个基本JQuery的插件
		
如何创建一个基本的插件 有时您希望在整个代码中提供一些功能.例如,也许你想要一个单一的方法,你可以调用一个jQuery选择,对选择执行一系列的操作.在这种情况下,您可能需要编写一个插件. 链接jQue ...
 - 使用jQuery.extend创建一个简单的选项卡插件
		
选项卡样式如图,请忽略丑陋的样式,样式可以随意更改 主要是基于jquery的extend扩展出的一个简单的选项卡插件,注意:这里封装的类使用的是es6中的class,所以不兼容ie8等低版本浏览器呦! ...
 - 创建VS Code 扩展插件
		
VS Code提供了强大的扩展功能,我们可以通过开发插件实现自己的业务模型编辑器.这里我们快速介绍一下插件的创建.开发和发布过程. 创建插件开发模板 首先需要确认系统中安装了node.js,并且可以使 ...
 - [K/3Cloud] 创建一个单据转换插件
		
概念: 创建一个业务单据转换插件,在单据转换的各个时点干预单据转换的相关逻辑控制. 示例: 新建一个类,继承自单据转换插件基类Kingdee.BOS.Core.Metadata.ConvertElem ...
 - 如何利用WordPress创建自定义注册表单插件
		
来源:http://www.ido321.com/1031.html 原文:Creating a Custom WordPress Registration Form Plugin 译文:创建一个定制 ...
 - 如何创建一个自定义jQuery插件
		
简介 jQuery 库是专为加快 JavaScript 开发速度而设计的.通过简化编写 JavaScript 的方式,减少代码量.使用 jQuery 库时,您可能会发现您经常为一些常用函数重写相同的代 ...
 - 【转】怎样创建一个Xcode插件(Part 1)
		
原文:How To Create an Xcode Plugin: Part 1/3 原作者:Derek Selander 译者:@yohunl 译者注:原文使用的是xcode6.3.2,我翻译的 ...
 
随机推荐
- dotNet core 应用部署centos
			
---恢复内容开始--- 阅读目录 需要安装的插件以及支撑架构 安装dotnetSDK 安装jexus 安装supervisord 遇到问题汇总 注意事项.扩展延伸 需要安装的插件以及支撑架构 1.d ...
 - 初识GitHub与Git
			
在初次接触GitHub的时候,英语渣渣本渣真是深感无奈啊..... ORZ 在好友的帮助下,也算是初步入门了吧. 谨以此文作为初级使用手册记录,希望能帮助到你. 一.首先要申请一个GitHub账户 二 ...
 - Brainteaser-292. Nim Game
			
You are playing the following Nim Game with your friend: There is a heap of stones on the table, eac ...
 - HDU 6205(尺取法)2017 ACM/ICPC Asia Regional Shenyang Online
			
题目链接 emmmm...思路是群里群巨聊天讲这题是用尺取法.....emmm然后就没难度了,不过时间上3000多,有点.....盗了个低配本的读入挂发现就降到2800左右, 翻了下,发现神犇Clar ...
 - apicloud  基础
			
时间成本 人力成本 很多人想开发app 又碍于时间和金钱成本 . 本色对app 要求不高的话. 混合app 开发是一种很好的方式. apicloud 就是一种很好的方式. apicloud ...
 - Android之系统架构
			
Android 是Google开发的基于Linux平台的开源手机操作系统.它包括操作系统.用户界面和应用程序 —— 移动电话工作所需的全部软件,而且不存在任何以往阻碍移动产业创新的专有权障碍.Andr ...
 - MVC4删除 pages引发的异常 System.Web.Optimization找不到引用
			
在MVC4的开发中,如果创建的项目为空MVC项目,那么在App_Start目录下没有BundleConfig.cs项的内容,在手动添加时在整个库中都找不到:System.Web.Optimizatio ...
 - 指定nginx某个目录显示目录结构
			
1.修改配置文件/usr/local/nginx/conf/nginx.conf 指定目录,开启autoindex为on. location /study { autoindex on; } 2. 保 ...
 - PostgreSQL 数据库错误代码解释
			
PostgreSQL 服务器发出的所有消息都赋予了五个字符 的错误代码, 这些代码遵循 SQL 的 "SQLSTATE" 代码的习惯.需要知道发生了什么错误条件的应用通常应该测试错 ...
 - 【JXOI2018】排序问题 贪心
			
我们令$sum_i$表示数字i在加完数字的数列中出现的次数,那么答案显然为$\dfrac{(n+m)!}{\sum_{i=0}^{\infty}sum_i!}$ 不难发现,当每次添加的数为$[l,r] ...