修改 Outlook 电子邮件的附件
本主题介绍如何以编程方式修改 Microsoft Outlook 电子邮件附件而不更改原始文件。
提供者: Ken Getz, MCW Technologies, LLC
发送包含一个或多个附件的电子邮件非常简单,不论是在 Outlook 界面中发送还是以编程方式发送。 但是在某些情况下,您可能希望能够在将其附加到邮箱后对附件进行修改,而不更改文件系统中的原始文件。 换句话说,您可能需要以编程方式访问内存中附件的内容。
例如,想象一下,您的应用程序需要将扩展名为 .txt 的所有附件中的文本转换为大写。 在托管 Outlook 外接程序中,可以轻松处理 ItemSend 事件。 在该事件中,执行相关工作,然后再发送邮件。 此方案的难点在于检索附件内容以修改每个文本文件的内容。
本主题中的示例代码演示如何使用 Attachment 接口的 GetProperty (String) 和 SetProperty (String、Object) 方法解决此特定问题。 在任意一种情况下,您提供一个包含 MAPI 属性 PidTagAttachDataBinary 的值,以获取(并设置)附件的内容。
注意PidTagAttachDataBinary 属性的命名空间表示形式为 https://schemas.microsoft.com/mapi/proptag/0x37010102
。 有关在命名空间引用的属性上使用 PropertyAccessor 对象的详细信息,请参阅 通过命名空间引用属性。
示例代码处理邮件项目的 ItemSend 事件。 在自定义事件处理器中,对于任何扩展名为 .txt 的附件,代码将调用 ConvertAttachmentToUpperCase
方法。 ConvertAttachmentToUpperCase
提取 Attachment 对象和 MailItem 对象作为输入参数,检索填充了附件内容的字节数组,将字节数组转换为字符串,将字符串转换为大写,然后将附件内容设置为转换字符串作为字节数组。
下面的托管代码示例是使用 C# 和 Visual Basic 编写的。 若要运行需调入组件对象模型 (COM) 的 .NET Framework 托管代码示例,您必须使用可定义托管接口并将其映射到对象模型类型库中的 COM 对象的互操作程序集。 对于 Outlook,您可以使用 Visual Studio 和 Outlook 主互操作程序集 (PIA)。 在您运行适用于 Outlook 2013 的托管代码示例之前,请确保您已安装了 Outlook 2013 PIA 并且已添加了对 Visual Studio 中的 Microsoft Outlook 15.0 对象库组件的引用。
应使用适用于 Visual Studio) 的 Office 开发人员工具在 Outlook 外接程序 (类中使用以下代码示例 ThisAddIn
。 代码中的 应用程序对象必须是由 提供的受信任 Outlook ThisAddIn.Globals
对象。 有关使用 Outlook PIA 开发托管 Outlook 解决方案的详细信息,请参阅欢迎使用 MSDN 上的 Outlook 主互操作程序集参考 。
以下代码说明如何以编程方式修改 Outlook 电子邮件附件,而不更改原始文件。 若要演示此功能,请在 Visual Studio 中创建名为 ModifyAttachmentAddIn
的新托管 Outlook 外接程序。 将 ThisAddIn.cs 或 ThisAddIn.vb 中的代码替换为以下代码。
注意 若要访问附件数据,必须使用 MailItem.Save 方法保存邮件 项目。
using Outlook = Microsoft.Office.Interop.Outlook;
namespace ModifyAttachmentAddIn
{
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(Application_ItemSend);
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
void Application_ItemSend(object Item, ref bool Cancel)
{
Outlook.MailItem mailItem = Item as Outlook.MailItem;
if (mailItem != null)
{
var attachments = mailItem.Attachments;
// If the attachment a text file, convert its text to all uppercase.
foreach (Outlook.Attachment attachment in attachments)
{
ConvertAttachmentToUpperCase(attachment, mailItem);
}
}
}
private void ConvertAttachmentToUpperCase(Outlook.Attachment attachment, Outlook.MailItem mailItem)
{
const string PR_ATTACH_DATA_BIN =
"https://schemas.microsoft.com/mapi/proptag/0x37010102";
// Confirm that the attachment is a text file.
if (System.IO.Path.GetExtension(attachment.FileName) == ".txt")
{
// There are other heuristics you could use to determine whether the
// the attachment is a text file. For now, keep it simple: Only
// run this code for *.txt.
// Retrieve the attachment as an array of bytes.
var attachmentData =
attachment.PropertyAccessor.GetProperty(
PR_ATTACH_DATA_BIN);
// Convert the byte array into a Unicode string.
string data = System.Text.Encoding.Unicode.GetString(attachmentData);
// Convert to upper case.
data = data.ToUpper();
// Convert the data back to an array of bytes.
attachmentData = System.Text.Encoding.Unicode.GetBytes(data);
//Set PR_ATTACH_DATA_BIN to attachmentData.
attachment.PropertyAccessor.SetProperty(PR_ATTACH_DATA_BIN,
attachmentData);
}
}
#region VSTO generated code
/// <summary>
/// Required method for Designer support - don't 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
}
}
Public Class ThisAddIn
Private Sub ThisAddIn_Startup() Handles Me.Startup
End Sub
Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
End Sub
Private Sub Application_ItemSend(ByVal Item As Object, _
ByRef Cancel As Boolean) Handles Application.ItemSend
Dim mailItem As Outlook.MailItem = TryCast(Item, Outlook.MailItem)
If mailItem IsNot Nothing Then
Dim attachments = mailItem.Attachments
For Each attachment As Outlook.Attachment In attachments
' If the attachment is a text file, convert to uppercase.
ConvertAttachmentToUpperCase(attachment, mailItem)
Next attachment
End If
End Sub
Private Sub ConvertAttachmentToUpperCase(ByVal attachment As Outlook.Attachment, _
ByVal mailItem As Outlook.MailItem)
Const PR_ATTACH_DATA_BIN As String = "https://schemas.microsoft.com/mapi/proptag/0x37010102"
' Confirm that the attachment is a text file.
If System.IO.Path.GetExtension(attachment.FileName) = ".txt" Then
' There are other heuristics you could use to determine whether the
' the attachment is a text file. For now, keep it simple: Only
' run this code for *.txt.
' Retrieve the attachment as an array of bytes.
Dim attachmentData = attachment.PropertyAccessor.GetProperty(PR_ATTACH_DATA_BIN)
' Convert the byte array into a Unicode string.
Dim data As String = System.Text.Encoding.Unicode.GetString(attachmentData)
' Convert to upper case.
data = data.ToUpper()
' Convert the data back to an array of bytes.
attachmentData = System.Text.Encoding.Unicode.GetBytes(data)
'Set PR_ATTACH_DATA_BIN to attachmentData.
attachment.PropertyAccessor.SetProperty(PR_ATTACH_DATA_BIN, attachmentData)
End If
End Sub
End Class
另请参阅
支持和反馈
有关于 Office VBA 或本文档的疑问或反馈? 请参阅 Office VBA 支持和反馈,获取有关如何接收支持和提供反馈的指南。