修改 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

另请参阅

向邮件项附加文件

将 Outlook 联系人项目附加到电子邮件

限制 Outlook 电子邮件的附件大小

支持和反馈

有关于 Office VBA 或本文档的疑问或反馈? 请参阅 Office VBA 支持和反馈,获取有关如何接收支持和提供反馈的指南。