Eugene Astafiev

How To: Add an attachment to an Outlook e-mail message

Sometimes developers need to create an add-in, which automatically sends reports based on some rules. The report can hold one or more attachments with the data the recipient needs. Today I will show you how to attach something to the e-mail message programmatically.

The Attachments class in Outlook provides the Add function for this task. It returns a variable, which represents the new attachment. The Add function accepts four parameters:

  1. The source of attachment. It will be a file path in case the attachment is a file or an Outlook item (MailItem, AppointmentItem, ContactItem and etc.)
  2. The type of attachment. The OlAttachmentType enumeration is used for specifying the type and can have one of the following values: olByReference (a shortcut to the location of the original file), olByValue (a copy of the original file that can be accessed even if the original file is removed), olEmbeddeditem (an Outlook message format file (*.msg) that is a copy of the original one) and olOLE (an OLE document). This is an optional parameter.
  3. The position of the attachment, i.e. where the attachment should be placed within the body text of the message. This optional parameter can be applied to the Rich Text format e-mails only. However, if you pass 0, the attachment will be hidden.
  4. The display name of the attachment. It can be applied to the Rich Text format e-mails when the type is set to the olByValue value. This is an optional parameter as well.

When you add a new attachment to the e-mail message, the type of the added attachment may stay set to the olOLE value. So, please don't forget to call the Save method of the MailItem object right after you add an attachment. It will allow you to keep away from various issues you may face.

The following code adds an attachment to the e-mail message that is currently open in the inspector window. To get the code running you need to pass an instance of the Outlook Application class to the AddAttachmentFromFile method. In Add-in Express based add-ins you can retrieve it using the OutlookApp property of the add-in module and in VSTO based add-ins please use the Application property of the add-in class.

C# and Add-in Express:

private void AddAttachmentFromFile(Outlook._Application OutlookApp)
{
    Outlook.Inspector activeInspector = OutlookApp.ActiveInspector();
    if (activeInspector != null)
    {
        Outlook.MailItem activeMailItem = activeInspector.CurrentItem as Outlook.MailItem;
        if (activeMailItem != null)
        {
            Outlook.Attachments mailAttachments = activeMailItem.Attachments;
            // the last two arguments can be applied if the Rich Text format is used 
            Outlook.Attachment newAttachment = mailAttachments.Add(
                @"C:\Text Document.txt", Outlook.OlAttachmentType.olByValue, 
                1, "The test attachment");
            activeMailItem.Save();
            // don't forget to release underlying COM objects
            if (newAttachment != null) Marshal.ReleaseComObject(newAttachment);
            if (mailAttachments != null) Marshal.ReleaseComObject(mailAttachments);
            Marshal.ReleaseComObject(activeMailItem);
        }
        Marshal.ReleaseComObject(activeInspector);
    }
}

VB.NET and Add-in Express:

Private Sub AddAttachmentFromFile(OutlookApp As Outlook._Application)
    Dim activeInspector As Outlook.Inspector = OutlookApp.ActiveInspector()
    If Not IsNothing(activeInspector) Then
        Dim activeMailItem As Outlook.MailItem = activeInspector.CurrentItem
        If Not IsNothing(activeMailItem) Then
            Dim mailAttachments As Outlook.Attachments = activeMailItem.Attachments
            ' the last two arguments can be applied if the Rich Text format is used 
            Dim newAttachment As Outlook.Attachment = mailAttachments.Add( _
                "C:\Text Document.txt", Outlook.OlAttachmentType.olByValue, _ 
                 1, "The test attachment")
            activeMailItem.Save()
            ' don't forget to release underlying COM objects
            If Not IsNothing(newAttachment) Then 
                Marshal.ReleaseComObject(newAttachment)
            End If
            If Not IsNothing(mailAttachments) Then 
                Marshal.ReleaseComObject(mailAttachments)
            End If
            Marshal.ReleaseComObject(activeMailItem)
        End If
        Marshal.ReleaseComObject(activeInspector)
    End If
End Sub

C# and VSTO:

using System.Runtime.InteropServices;
// ...
private void AddAttachmentFromFile(Outlook.Application Application)
{
    Outlook.Inspector activeInspector = Application.ActiveInspector();
    if (activeInspector != null)
    {
        Outlook.MailItem activeMailItem = activeInspector.CurrentItem as Outlook.MailItem;
        if (activeMailItem != null)
        {
            Outlook.Attachments mailAttachments = activeMailItem.Attachments;
            // the last two arguments can be applied if the Rich Text format is used
            Outlook.Attachment newAttachment = mailAttachments.Add(
               @"C:\Text Document.txt", Outlook.OlAttachmentType.olByValue, 
               1, "The test attachment");
            activeMailItem.Save();
            // don't forget to release underlying COM objects
            if (newAttachment != null) Marshal.ReleaseComObject(newAttachment);
            if (mailAttachments != null) Marshal.ReleaseComObject(mailAttachments);
            Marshal.ReleaseComObject(activeMailItem);
         }
         Marshal.ReleaseComObject(activeInspector);
     }
}

VB.NET and VSTO:

Imports System.Runtime.InteropServices
' ...
Private Sub AddAttachmentFromFile(Application As Outlook.Application)
    Dim activeInspector As Outlook.Inspector = Application.ActiveInspector()
    If Not IsNothing(activeInspector) Then
        Dim activeMailItem As Outlook.MailItem = activeInspector.CurrentItem
        If Not IsNothing(activeMailItem) Then
            Dim mailAttachments As Outlook.Attachments = activeMailItem.Attachments
            ' the last two arguments can be applied if the Rich Text format is used 
            Dim newAttachment As Outlook.Attachment = mailAttachments.Add( _
                "C:\Text Document.txt", Outlook.OlAttachmentType.olByValue, _
                1, "The test attachment")
            activeMailItem.Save()
            ' don't forget to release underlying COM objects
            If Not IsNothing(newAttachment) Then 
                Marshal.ReleaseComObject(newAttachment)
            End If 
            If Not IsNothing(mailAttachments) Then 
                Marshal.ReleaseComObject(mailAttachments)
            End If
            Marshal.ReleaseComObject(activeMailItem)
        End If
        Marshal.ReleaseComObject(activeInspector)
    End If
End Sub

See you on our forums and in the e-mail support!

8 Comments

  • https://secure.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=32 Hameem says:

    nice to see this post.i like to ask one question, my web application which is running in the IIS 7.0 , Client accessing my web app and they are attaching the file from location of from there own PC “C:\Text Document.txt” and trying to send a mail but my web app seraching the same URL in the server machine and giving error as “cannot find path” so how can i resolve such kind of problem.

    thanks in advanced

  • https://secure.gravatar.com/avatar/bbd979ae5b772d0bc1f82065aa4ba146?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Eugene Astafiev says:

    Hi Hameem,

    Thank you for your comment.

    Sorry, but I don’t know the answer. This question is beyond my area of expertise.

  • https://secure.gravatar.com/avatar/7f46cfc3d895732165a80217ea5edcba?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G db says:

    Thanks Eugene. I have a question.

    How would you attach multiple items from a folder? Say, I have folder with 20 documents. In my current work, I can attach them just fine to new mail message. But if I cancel that message, then attach them again, Outlook crashes and I dont even get any error. I am getting this consistently, most of the times when I try to attach for 2nd time, sometimes for 3rd time like this:

    1. I get items from selection
    2. attach items to MailItem
    3. New mail message opens with my attachments
    4. instead of sending it, I choose to close it and choose No to save it
    5. Then again get items from selection and try to attach them
    6. However, this time call to MailItem.Attachments.Add(…) will crash Outlook

    Much appreciated

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Hello db,

    This looks like the issue occurs because you don’t release COM objects created in your code. Please check section Releasing COM objects at https://www.add-in-express.com/docs/net-office-tips.php#releasing.

    HTH

  • https://secure.gravatar.com/avatar/7f46cfc3d895732165a80217ea5edcba?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G db says:

    @AndreySmolin I read the article above by Eugene Astafiev and added calls to release COM objects. You can see them in my code below but I am still having the issue which is when I attach items to new mail for the 1st time, it always works fine but if I close that new mail form (with my attachments) and try to attach them for the 2nd time, Outlook will crash.
    Here is the code with modification as per Eugene’s blog above:

    public void SendAttachmentsClick()
    {
    Microsoft.Office.Interop.Outlook.MailItem oMailItem = HostAddIn.Application.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
    oMailItem.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML;
    Selection olSelection = HostAddIn.ActiveExplorer.Selection;

    // //returns strings representing paths to documents I want to attach
    List paths = GetAttachmentsPaths();
    if (paths.Count > 0)
    {
    try
    {
    Microsoft.Office.Interop.Outlook.Attachments mailAttachments = oMailItem.Attachments;
    foreach (string itemPath in paths)
    {
    Microsoft.Office.Interop.Outlook.Attachment newAttachment = mailAttachments.Add(itemPath);
    oMailItem.Save();
    if (newAttachment != null) Marshal.ReleaseComObject(newAttachment);
    }
    if (mailAttachments != null) Marshal.ReleaseComObject(mailAttachments);

    if (oMailItem.Attachments.Count > 0)
    {
    oMailItem.Display(false);
    }
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }
    finally
    {
    if (oMailItem != null)
    {
    Marshal.ReleaseComObject(oMailItem);
    oMailItem = null;
    }
    Marshal.ReleaseComObject(olSelection);
    }
    }
    }

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    The first rule given in that article is:

    Don’t chain COM calls like in OutlookApp.Explorers.Count, ExcelApp.Workbooks[1] (C#) or PowerPointApp.Presentations.Item(1) (VB.NET).

    Below are listed calls that break these rule:
    – HostAddIn.ActiveExplorer.Selection
    – oMailItem.Attachments.Count

    If the issue is reproducible, comment out blocks of your code to find the code that produces the issue.

  • https://secure.gravatar.com/avatar/7f46cfc3d895732165a80217ea5edcba?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G db says:

    this simply has no effect. I tried it. the block that fails is when attachment is added to MailItem.Attachments. Thanks anyways.

  • https://secure.gravatar.com/avatar/29957f26ad2d8ba527fd9cc8cfa7b2e0?s=32&d=https%3A%2F%2Fsecure.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Andrei Smolin (Add-in Express Team) says:

    Make sure all other COM add-ins are disabled. Install all updates on Office and .NET.

Post a comment

Have any questions? Ask us right now!