如何创建 Microsoft Outlook 的插件






4.69/5 (14投票s)
这是一个关于如何创建 VSTO 加载项以扩展 Microsoft Outlook 功能的教程。
1. 引言
Visual Studio Tools for Office (VSTO) 加载项是 .NET Framework 中提供的一种工具集,它允许我们扩展和自定义 Microsoft Office 产品(2003 及更高版本)。
在本教程中,我们将以 Outlook 2013 为案例研究,并使用 Visual Studio 2015。
2. Outlook 对象模型
这是创建 Outlook 加载项的起点,理解这些对象的含义很重要。
Outlook 对象模型
Application
:代表 Outlook 应用程序,是模型中最高级的对象。此对象是访问模型中其他对象的起点。Explorer
:代表一个显示文件夹内容的窗口,例如电子邮件、消息、任务、约会等。Inspector
:代表一个显示项的窗口,例如电子邮件消息、任务、约会等。MAPIFolder
:代表一个包含电子邮件、联系人、约会等的文件夹。
注意:此对象已废弃,应改用 Folder 对象代替MAPIFolder
。MailItem
:代表一封电子邮件。AppointmentItem
:代表日历文件夹中的会议、一次性约会、计划约会或会议。TaskItem
:代表在指定时间范围内要执行的任务。ContactItem
:代表“联系人”文件夹中的一个联系人。
3. 如何开始
在下一节中,我们将开始学习这类应用程序。
3.1. 如何创建项目
- 启动 Visual Studio。
- 文件菜单 / 新建 / 项目。
- 在项目模板面板中,打开 Visual C#,Office/SharePoint,Office 加载项。
- 选择 Outlook 2013 和 2016 VSTO 加载项模板。
- 填写项目名称,然后单击确定。
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
对象和其他对象模型。此外,我们还可以执行初始化过程,例如配置和访问数据库。
ThisAddIn_Shutdown
方法在用户关闭 Outlook 时执行。但需要注意的是,在当前版本中,由于性能问题,此方法未被调用。但是,如果需要在 Outlook 关闭时执行某些代码,可以参考 此链接 以获取替代方法。
3.3. Application 对象和其他模型对象
接下来,我们将看到如何获取其他对象模型。为此,我们需要使用所需的命名空间
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 中转到“生成”菜单,然后单击“清理解决方案”选项。
3.5. 如何制作安装程序
在 Visual Studio 中,转到“生成”菜单 / “发布...” 。
注意:有时,Visual Studio 生成的安装程序在用户计算机上安装时可能会失败,并且您会收到以下错误消息
引用“属性“type”的值无法解析。错误是:无法加载文件或程序集…” 。
4. 基本示例
在下一节中,我们将看到一些关于创建 VSTO Outlook 2013 加载项的示例。
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# 桌面应用程序一样。让我们为 button 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 应用程序中使用的版本很重要,同时也要选择工具和实用程序的引用。
在本例中,我使用的是 Outlook 的 15.0.0.0 版本。
因此,我们将选择相同版本的 Word 引用。
5.1. 如何从功能区按钮获取电子邮件消息中的选定文本
以下示例发生在添加到 Ribbon
的按钮的 OnClick
事件中(请参阅上一节 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
属性,我们得到一个由用户选择的所有单词的集合,而 First
属性是用户单击的位置。
下图发生在用户创建新电子邮件时。在此图中,我们可以看到应用程序显示一条消息,其中包含用户双击的文本。
6. 结论
如您所见,我们可以通过 VSTO 加载项工具以许多简单的方式扩展 Outlook 的功能。在我看来,这类应用程序在企业领域有许多需求,可以快速解决一些问题,而且,通常办公室用户比其他应用程序更习惯使用 Microsoft Office 产品。通过 VSTO 加载项,我们可以查询数据库以获取员工联系人、产品列表以包含在电子邮件中、在企业应用程序和 Outlook 之间同步约会等等。