How to: Modify an Attachment of an Outlook Email Message
This topic describes how you can programmatically modify a Microsoft Outlook email attachment without changing the original file.
Provided by: Ken Getz, MCW Technologies, LLC
Sending an email message with one or more attachments is easy, both in the Outlook interface and programmatically. In some scenarios, however, you may want to be able to modify the attachment after it has been attached to the mail item, without changing the original file in the file system. In other words, you may need a programmatic way to access the contents of the attachment in memory.
For example, imagine that your application requires converting the text in all attachments that have a .txt extension to uppercase. In a managed Outlook add-in, you can easily handle the ItemSend event. In that event, perform the work before sending the mail item. The difficult part of the scenario is in retrieving the contents of the attachments to modify the contents of each text file.
The sample code in this topic demonstrates how to solve this particular problem, using the GetProperty(String) and SetProperty(String, Object) methods of the Attachment interface. In each case, you supply a value that contains the MAPI property PidTagAttachDataBinary to obtain (and then set) the contents of the attachment.
The namespace representation of the PidTagAttachDataBinary property is http://schemas.microsoft.com/mapi/proptag/0x37010102. For more information about using the PropertyAccessor object on properties that are referenced by namespace, see Referencing Properties by Namespace.
The sample code handles the ItemSend event of a mail item. In the custom event handler, for any attachment that has a .txt extension, the code calls the ConvertAttachmentToUpperCase method. ConvertAttachmentToUpperCase takes an Attachment object and a MailItem object as input arguments, retrieves a byte array that is filled with the contents of the attachment, converts the byte array to a string, converts the string to uppercase, and then sets the contents of the attachment to the converted string as a byte array.
The following managed code samples are written in C# and Visual Basic. To run a .NET Framework managed code sample that needs to call into a Component Object Model (COM), you must use an interop assembly that defines and maps managed interfaces to the COM objects in the object model type library. For Outlook, you can use Visual Studio and the Outlook Primary Interop Assembly (PIA). Before you run managed code samples for Outlook 2013, ensure that you have installed the Outlook 2013 PIA and have added a reference to the Microsoft Outlook 15.0 Object Library component in Visual Studio. You should use the following code samples in the ThisAddIn class of an Outlook add-in (using Office Developer Tools for Visual Studio). The Application object in the code must be a trusted Outlook Application object provided by ThisAddIn.Globals. For more information about using the Outlook PIA to develop managed Outlook solutions, see the Welcome to the Outlook 2013 Primary Interop Assembly Reference on MSDN.
The following code shows how to programmatically modify an Outlook email attachment without changing the original file. To demonstrate this functionality, in Visual Studio, create a new managed Outlook add-in named ModifyAttachmentAddIn. Replace the code in ThisAddIn.cs or ThisAddIn.vb with the following code.
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 = "http://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