Click here to Skip to main content
13,591,950 members
Click here to Skip to main content
Add your own
alternative version


17 bookmarked
Posted 6 Dec 2012
Licenced CPOL

How to extract exchange attachments using Exchange Web Services and VB.NET

, 7 Dec 2012
Rate this:
Please Sign up or sign in to vote.
This article demonstrates how to extract attachments from Exchange using VB.NET.


In this article I present a short form load event that you can place into a blank WinForms project and once you provide the appropriate values to the public variables in the uppermost portion of the code you should be able to run the application and see that it will extract all attachments from a defined Exchange mailbox to a local file.


This is a small portion of an application I made that searches and extracts certain attachments from a specific Exchange 2007 mailbox and once extracted were read via StreamReader and their fixed length string contents were uploaded to a SQL instance. This article covers the first part of that task because I found little information when trying to connect to EWS to extract attachments, at least for VB.NET.


I have a portion of the completed code below that has logic to delete the messages it extracts attachments from but I have commented this portion out. I left it intact so that you may uncomment this if deleting the messages is something you wanted to do. I found that I had to delete the messages on my project because otherwise the mailbox would take too long to process and the application would eventually timeout, which can be adjusted but that is beyond the scope of this article.

Add a Web Reference

You will need the URL for your Exchange Web Service, which is also the URL you decalare in the below Global Variable named strExchAsmx. As instructed here you add a web reference in VS2010 by adding a Service Reference, press advanced and then add a Web reference.


Instead of breaking the code into smaller blocks and providing instruction I have opted to add comment info in the code so that if you cut and paste it is available to you in your project.

Import these classes. You will likely get an error on the because this is the name of my project and web reference. Here you need to import the web reference that you created above.

Imports System.Net
Imports System.IO
Imports System.Text

Declare these Global Variables

Public strUsername As String = "mailboxusernamehere"
Public strPassword As String = "mailboxpasswordhere"
Public strExchAsmx As String = "https://yourexchangeserverhere/EWS/Exchange.asmx"
Public strAttachPath As String = "C:\Mail\"

Place this in the pageload event or whatever subroutine you want to initate the process

Using exchangeServer As New ExchangeServiceBinding()

    ' This portion uses the credentials you provided and 
    ' initiates the connection to the Web Service
    Dim creds As ICredentials = New NetworkCredential(strUsername, strPassword)
    exchangeServer.Credentials = creds
    exchangeServer.Url = strExchAsmx

    ' Since this is not a folder search we opt for Shallow Traversal Type
    Dim findItemRequest As New FindItemType()
    findItemRequest.Traversal = ItemQueryTraversalType.Shallow

    ' The BaseShape property Gets or Sets the requested 
    ' properties to return in a response
    Dim itemProperties As New ItemResponseShapeType()
    itemProperties.BaseShape = DefaultShapeNamesType.AllProperties

    ' Here the item shape property is set, Go To definition on 
    ' FindItemType for more info
    findItemRequest.ItemShape = itemProperties

    ' Setup a folder array and define the folder Name and then set the parent 
    ' folder ID Field with it to filter the search to just the inbox. 
    Dim folderIDArray As DistinguishedFolderIdType() = New DistinguishedFolderIdType(0) {}
    folderIDArray(0) = New DistinguishedFolderIdType()
    folderIDArray(0).Id = DistinguishedFolderIdNameType.inbox
    findItemRequest.ParentFolderIds = folderIDArray

    ' This block initiates the reading of the messages, 
    ' Declares variables for the folder and items in that folder
    Dim findItemResponse As FindItemResponseType = exchangeServer.FindItem(findItemRequest)
    Dim folder As FindItemResponseMessageType = _
    DirectCast(findItemResponse.ResponseMessages.Items(0), FindItemResponseMessageType)
    Dim folderContents As New ArrayOfRealItemsType()
    folderContents = DirectCast(folder.RootFolder.Item, ArrayOfRealItemsType)
    Dim items As ItemType() = folderContents.Items

    ' if there are no items in the folder (Inbox) then exit
    If items Is Nothing OrElse items.Count() <= 0 Then
        MsgBox("No Items Found!")
        Exit Sub
    End If

    ' Get the encoded ids of each item
    Dim itemIds As BaseItemIdType() = New BaseItemIdType(items.Count() - 1) {}
    For i As Integer = 0 To items.Count() - 1
        itemIds(i) = items(i).ItemId

    ' GetItemType is a class that represents a 
    ' request to get items from a mailbox
    Dim getItemType As New GetItemType()

    ' GetItemType variable here is defining the 
    ' items to get in that request
    getItemType.ItemIds = itemIds
    getItemType.ItemShape = New ItemResponseShapeType()
    getItemType.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties
    getItemType.ItemShape.BodyType = BodyTypeResponseType.Text
    getItemType.ItemShape.BodyTypeSpecified = True

    ' This is the response from the exchange server with a number of messages 
    ' that fit the parameters of the request
    Dim getItemResponse As GetItemResponseType = exchangeServer.GetItem(getItemType)
    Dim messages As ItemType() = New ItemType(getItemResponse.ResponseMessages.Items.Count() - 1) {}
    Dim f As Integer = 0
    Dim j As Integer = 0
    Dim h As Integer = 0

    ' Here we loop through each message in that response and 
    ' if we find an attachment we extract it
    For j = 0 To messages.Count() - 1

        'Here inside the loop we set the messages itemtype to 
        ' a single message in the exchange response
        messages(j) = DirectCast(getItemResponse.ResponseMessages.Items(j), _

        ' We evaluate the message to see if it has attachments, 
        ' we have no else portion so on to the next message
        If (messages(j).HasAttachments = True) Then
            f = f + 1
            ' In this block we see what is attached and get the resulting 
            ' attachment id so that we can extract it
            Dim request As New GetAttachmentType()
            Dim responseShape As New AttachmentResponseShapeType()
            responseShape.BodyType = BodyTypeResponseType.Text
            responseShape.BodyTypeSpecified = True
            request.AttachmentShape = responseShape
            Dim ids As RequestAttachmentIdType() = New RequestAttachmentIdType(0) {}
            ids(0) = New RequestAttachmentIdType()
            ids(0).Id = Convert.ToString(messages(j).Attachments(0).AttachmentId.Id)
            request.AttachmentIds = ids

                ' Here we request the attachment from the exchange server
                Dim response As GetAttachmentResponseType = exchangeServer.GetAttachment(request)
                Dim rmta As ResponseMessageType() = response.ResponseMessages.Items

                ' For each attachment in the request per attachment ID within the single message
                ' we will get the attachment type and process each accordingly
                For Each responseMessage As ResponseMessageType In rmta
                    Dim airmt As AttachmentInfoResponseMessageType = _
                    TryCast(responseMessage,  _

                    Dim attachments As AttachmentType() = airmt.Attachments
                    For Each attachment As AttachmentType In attachments

                        ' Based on what the file type is it will be process or converted differently
                        ' This portion does that.  I have used this with word documents and images.
                        If TypeOf attachment Is FileAttachmentType Then
                            Dim TheFileAttachment As FileAttachmentType = _
                                DirectCast(attachment, FileAttachmentType)
                            Using File2Disk As Stream = New  _
                                FileStream(strAttachPath & "\" & _
                                messages(j).Attachments(0).Name, FileMode.Create)
                                File2Disk.Write(TheFileAttachment.Content, 0, _
                            End Using
                            Dim TheItemAttachment As ItemType = _
                                DirectCast(attachment, ItemAttachmentType).Item
                            Dim ContentBytes() As Byte = _
                            Using Item2Disk As Stream = New  _
                                FileStream(strAttachPath & "\" & _
                                messages(j).Attachments(0).Name + ".eml", FileMode.Create)
                                Item2Disk.Write(ContentBytes, 0, ContentBytes.Length)
                            End Using
                        End If
                        h = h + 1
            Catch x As Exception
            End Try

            '' Remove these comments to delete messages after being extracted.
            'Dim dit As New DeleteItemType()
            'dit.ItemIds = New BaseItemIdType(0) {}
            'Dim itemId As New ItemIdType()
            'itemId.Id = messages(j).ItemId.Id
            'dit.ItemIds(0) = itemId
            'Dim diResponse As DeleteItemResponseType = exchangeServer.DeleteItem(dit)
        End If

    'This message is simply to show how many items were processed 
    ' and to serve as notice that the operation is complete
    MsgBox(j & " messages read, " & f & _
           " messages had attachments and " & h _
           & " of those attachments were extracted!")
End Using


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Robert E Campbell
Software Developer
United States United States
No Biography provided

You may also be interested in...


Comments and Discussions

QuestionI get an error with the certificates Pin
cowboy20666-Jul-15 11:49
membercowboy20666-Jul-15 11:49 
SuggestionDelete Message Pin
Member 91097621-Jul-14 23:55
memberMember 91097621-Jul-14 23:55 
QuestionError Pin
Member 1066027110-Mar-14 22:37
memberMember 1066027110-Mar-14 22:37 
Questionerror with exchangeServer.GetItem(getItemType) Pin
AcornElectron19-Feb-14 13:27
memberAcornElectron19-Feb-14 13:27 
AnswerRe: error with exchangeServer.GetItem(getItemType) Pin
Member 1026725822-Apr-15 4:31
memberMember 1026725822-Apr-15 4:31 
GeneralRetreiving mails Pin
dariok28-Oct-13 7:21
memberdariok28-Oct-13 7:21 
QuestionHow to access a 2003 Exchange Server Pin
VBSiv14-Oct-13 0:43
memberVBSiv14-Oct-13 0:43 
QuestionMark as read Pin
KrisKhairallah3-Oct-13 21:35
memberKrisKhairallah3-Oct-13 21:35 
GeneralMy vote of 5 Pin
Member 1026725824-Sep-13 9:20
memberMember 1026725824-Sep-13 9:20 
QuestionAttracting from custom folders Pin
Chad_robinson1-Aug-13 8:37
memberChad_robinson1-Aug-13 8:37 
QuestionNullReferenceException was unhandled Pin
snapsi4223-May-13 7:58
membersnapsi4223-May-13 7:58 
QuestionRe: NullReferenceException was unhandled Pin
Member 833336925-Mar-14 9:07
memberMember 833336925-Mar-14 9:07 
GeneralMy vote of 5 Pin
Savalia Manoj M21-Jan-13 2:50
memberSavalia Manoj M21-Jan-13 2:50 
QuestionError? Pin
i0013-Jan-13 13:24
memberi0013-Jan-13 13:24 
AnswerThis is a tip Pin
Clifford Nelson6-Dec-12 7:03
memberClifford Nelson6-Dec-12 7:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04-2016 | 2.8.180618.1 | Last Updated 7 Dec 2012
Article Copyright 2012 by Robert E Campbell
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid