Eugene Astafiev

How To: Perform Send/Receive in Outlook programmatically

Today I will continue my series of “How To” articles explaining the basics of Outlook development.

The NameSpace class in Outlook provides a programmatic equivalent of the “Send/Receive All” command (see Tools | Send/Receive in Outlook 2007 or below) – SendAndReceive method. This method allows you to initiate an immediate send/receive of e-mail messages submitted in the current session. It accepts a Boolean value indicating whether a progress bar should be displayed or not. However, if you don’t specify any value, the default behavior according to the user settings is expected.

The following code works like a charm in Outlook 2007 and 2010:

C#:

private void DirectSendAndReceiveCall(object sender, IRibbonControl control, bool pressed)
{
    Outlook.NameSpace ns = OutlookApp.GetNamespace("MAPI");
    ns.SendAndReceive(false);
    if (ns != null) Marshal.ReleaseComObject(ns);
}

VB.NET:

Private Sub DirectSendAndReceiveCall()
    Dim ns As Outlook.NameSpace = OutlookApp.GetNamespace("MAPI")
    ns.SendAndReceive(False)
    If Not IsNothing(ns) Then Marshal.ReleaseComObject(ns)
End Sub

However, what should we do if we want to use version-neutral interops? The answer is simple: the late-binding technology available in the .NET framework does the trick ;-)

C#:

private void SendReceiveUsingLateBinding()
{
    Outlook.NameSpace ns = OutlookApp.GetNamespace("MAPI");
    ns.GetType().InvokeMember("SendAndReceive", System.Reflection.BindingFlags.Instance |
       System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Public,
       null, ns, null);
    if (ns != null) Marshal.ReleaseComObject(ns);
}

VB.NET:

Private Sub SendReceiveUsingLateBinding()
    Dim ns As Outlook.NameSpace = OutlookApp.GetNamespace("MAPI")
    ns.GetType().InvokeMember("SendAndReceive", _
         System.Reflection.BindingFlags.Instance Or _
         System.Reflection.BindingFlags.InvokeMethod Or _
         System.Reflection.BindingFlags.Public, _
         Nothing, ns, Nothing)
    If Not IsNothing(ns) Then Marshal.ReleaseComObject(ns)
End Sub

But how can we call the SendAndReceive method in case of Outlook 2000, 2002 and 2003? The following code illustrates the way we can use to bridge the gap!

C#:

private void ExecuteSendReceiveButton()
{
    Outlook.Explorer explorer = null;
    Office.CommandBars cmdBars = null;
    Office.CommandBarButton btnSendAndReceive = null;
    try
    {
        explorer = OutlookApp.ActiveExplorer();
        cmdBars = explorer.CommandBars;
        // 5488 should be used for Outlook 2000, 2002
        btnSendAndReceive = cmdBars.FindControl(Office.MsoControlType.msoControlButton, 7095)
            as Office.CommandBarButton;
        if (btnSendAndReceive != null)
        {
            btnSendAndReceive.Execute();
        }
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show(ex.Message);
    }
    finally
    {
        if (btnSendAndReceive != null) Marshal.ReleaseComObject(btnSendAndReceive);
        if (cmdBars != null) Marshal.ReleaseComObject(cmdBars);
        if (explorer != null) Marshal.ReleaseComObject(explorer);
    }
}

VB.NET:

Private Sub ExecuteSendReceiveButton()
    Dim explorer As Outlook.Explorer = Nothing
    Dim cmdBars As Office.CommandBars = Nothing
    Dim btnSendAndReceive As Office.CommandBarButton = Nothing
    Try
        explorer = OutlookApp.ActiveExplorer()
        cmdBars = explorer.CommandBars
        // 5488 should be used for Outlook 2000, 2002
        btnSendAndReceive = cmdBars.FindControl(Office.MsoControlType.msoControlButton, 7095)
        If Not IsNothing(btnSendAndReceive) Then
            btnSendAndReceive.Execute()
        End If
    Catch ex As Exception
        System.Windows.Forms.MessageBox.Show(ex.Message)
    Finally
        If Not IsNothing(btnSendAndReceive) Then Marshal.ReleaseComObject(btnSendAndReceive)
        If Not IsNothing(cmdBars) Then Marshal.ReleaseComObject(cmdBars)
        If Not IsNothing(explorer) Then Marshal.ReleaseComObject(explorer)
    End Try
End Sub

As you see, I used the Execute method of the CommandBarButton class in Outlook to simulate the SendAndReceive method. You can use the BuiltInControlScanner utility to find the controls’ IDs (it is 7095 and 5488 in our case).

However, there is one more way to imitate the “Send/Receive” button – use the SyncObjects classes. The SyncObjects class represents the Send/Receive groups for the end-user. Each group is represented by the SyncObject class in the Outlook Object Model. Currently we are interested in the Start method which allows implementing the required functionality (synchronize Send/Receive groups). This method doesn’t accept any parameters and doesn’t return any value.

C#:

private void AlternativeWay()
{
    Outlook.NameSpace ns = null;
    Outlook.SyncObjects syncObjs = null;
    Outlook.SyncObject syncObj = null;
    try
    {
        ns = OutlookApp.GetNamespace("MAPI");
        syncObjs = ns.SyncObjects;
        for (int i = 1; syncObjs.Count >= i; i++)
        {
            syncObj = syncObjs.Item(i);
            if (syncObj != null)
            {
                syncObj.Start();
                Marshal.ReleaseComObject(syncObj);
            }
        }
     }
     catch (Exception ex)
     {
         System.Windows.Forms.MessageBox.Show(ex.Message);
     }
     finally
     {
         if (syncObjs != null) Marshal.ReleaseComObject(syncObjs);
         if (ns != null) Marshal.ReleaseComObject(ns);
     }
}

VB.NET:

Public Sub AlternativeWay()
    Dim ns As Outlook.NameSpace = Nothing
    Dim syncObjs As Outlook.SyncObjects = Nothing
    Dim syncObj As Outlook.SyncObject = Nothing
    Try
        ns = OutlookApp.GetNamespace("MAPI")
        syncObjs = ns.SyncObjects
        For i As Integer = 1 To syncObjs.Count
            syncObj = syncObjs.Item(i)
            If Not IsNothing(syncObj) Then
                syncObj.Start()
                Marshal.ReleaseComObject(syncObj)
            End If
        Next
    Catch ex As Exception
        System.Windows.Forms.MessageBox.Show(ex.Message)
    Finally
        If Not IsNothing(syncObjs) Then Marshal.ReleaseComObject(syncObjs)
        If Not IsNothing(ns) Then Marshal.ReleaseComObject(ns)
    End Try
End Sub

In this case there is one side effect: the Send/Receive progress window will not be shown to the user. The synchronization is performed silently.

There are four ways to initiate the send/receive process in Outlook. Which one to use depends on your needs!

22 Comments

  • makopung primary says:

    kindly update our express outlook to assist us to send/receive messeges

  • Eugene Astafiev says:

    Hi Makopung,

    Thank you for visiting our technical blog.

    Note, the article describes methods and properties from Microsoft Office Outlook. Unfortunately Outlook Express doesn’t provide such methods and properties.

  • Jaideep says:

    Hello Eugene,

    a very nice article!! i have been trying along similar lines to programmatically read emails from outlook 2007 using c#. i am able to conenct to outlook using follwoing code:
    app = new Outlook.Application();
    ns = app.GetNamespace(“MAPI”);
    ns.Logon(Settings.Default.OutlookProfile, Settings.Default.password, false, false);
    string criteria = “[Subject] = ‘with some specific subject'”;
    inboxFolder = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
    Outlook.Items oItems = inboxFolder.Items;
    Outlook.Items filteredItems = oItems.Restrict(criteria);
    Console.WriteLine(“total NJ emails:” + filteredItems.Count);
    for (int i = 1; i <= filteredItems.Count; i++)
    {
    Outlook.MailItem oMailItem = (Outlook.MailItem)filteredItems[i];
    mailBody = oMailItem.Body;
    //some operations to fetch info from email body

    }

    i am still trying to figure it out, how to sync or update outlook with latest emails which are residing in exchange server.

    Thanks,
    Jaideep

  • Eugene Astafiev says:

    Hi Jaideep,

    Did you try to use SyncObjects class from the Outlook Object Model for this task?

  • Jaideep says:

    Hello Eugene, Thanks!!my requirement is to fetch emails from a specific sender and parse its body. we are thinking of to create it as c# console application which would run as a scheduler.
    does SyncObjects requires the use of Add-in project.is it possible to use SyncObjects using Microsoft.Office.Interop.Outlook assembly?
    please suggest.

    Thanks,
    Jaideep

  • Eugene Astafiev says:

    Hi Jaideep,

    Yes, it is. The SyncObjects class comes from the Outlook Object Model and doesn’t depend on the Add-in Express classes. So, you can use it on your own.

  • Jaideep says:

    Hi Eugene,
    i am getting following error while compiling private void AlternativeWay() method:
    ‘Microsoft.Office.Interop.Outlook.SyncObjects’ does not contain a definition for ‘Item’ and no extension method ‘Item’ accepting a first argument of type ‘Microsoft.Office.Interop.Outlook.SyncObjects’ could be found (are you missing a using directive or an assembly reference?)

    syncObj = syncObjs.Item(i);

    i have added reference to Microsoft Outlook 12.0 Outlook Library reference from com components tab.

  • Eugene Astafiev says:

    Hi Jaideep,

    I regret to tell you but we provide technical support only for registered customers with active subscriptions. Which of our product do you use?

  • Jaideep says:

    Hi Eugene,
    we are not using any of your porduct, though we chanceed upon your blog while investigating above problem. thank you very much for your support to provide us the direction.

  • Eugene Astafiev says:

    You are welcome, Jaideep!

  • Patrick Ellis says:

    An absolutely brilliant article Eugene. Has completely solved the “emails sitting in drafts folder” problem when using Redemption.
    Thanks

  • Eugene Astafiev says:

    Hi Patrick,

    Thank you for the kind words ;-)

  • Bill Cadden says:

    I have a c# web application/web form which uses interop.outlook to send email and create tasks (just like you described). it works perfectly on my local machine but not when i publish to the server.
    i want it to use it such that that emails sent appear in the sender’s ‘sent box’. Is this concept just not allowed in a server environment? (The users internally here do have outlook opened so they are signed in.) Here is the snippet::

    using Outlook = Microsoft.Office.Interop.Outlook;

    OutLookMail sendRequestStatusUpdateViaEmail = new OutLookMail();

    public class OutLookMail
    {
    private Outlook.Application oApp;
    private Outlook._NameSpace oNameSpace;
    private Outlook.MAPIFolder oSentboxFolder;

    Outlook._MailItem oMailItem = (Outlook._MailItem)oApp.CreateItem(Outlook.OlItemType.olMailItem);
    oMailItem.SaveSentMessageFolder = oSentboxFolder;
    //…
    oMailItem.To = toValue;
    oMailItem.CC = ccValue;
    oMailItem.BCC = bccValue;

    oMailItem.HTMLBody = sHtml;

    oMailItem.Send();
    }

  • Eugene Astafiev says:

    Hi Bill,

    Where and how do you get the oApp object?

    Please take a look at the similar Opening Outlook with new e-mail from Asp.net blog entry for more information on this.

  • Sohaib Ameen says:

    Hi Eugene,

    I want to catch send/Receive event when outlook is done synchronising emails, so I can execute my add-in after that.

    Is there anyway I can do that in c#?
    your help will be much appreciated.

    thanks

  • Andrei Smolin (Add-in Express Team) says:

    Hello Sohaib,

    You need to intercept SyncStart, SyncEnd, and SyncProgress events; see https://msdn.microsoft.com/en-us/library/office/ff862356.aspx, https://msdn.microsoft.com/en-us/library/office/ff866270.aspx and https://msdn.microsoft.com/en-us/library/office/ff865672.aspx. Note that in Add-in Express these events are disabled by default due to the issue we described at https://social.msdn.microsoft.com/Forums/office/en-US/7a20664c-7650-4d61-9d5f-13f1d929a8cd/outlook-2013-automatic-sendreceive-doesnt-work-with-the-sample-addin-below?forum=outlookdev. To enable these events, see the HandleEvents property of the Outlook Events component (ADXOutlookAppEvents).

  • Amq says:

    Hi

    Anybody can help me regarding my below query, thanks in advance.

    I am using outlook 2010, where i want to execute a macro only when user press Send/Receive button in outlook 2010.

    There is no issue of macro i wrote in VB. I only want to execute macro before receiving emails, kindly help me if it is possible.
    Thank you

  • Andrei Smolin (Add-in Express Team) says:

    Hello Amq,

    See https://msdn.microsoft.com/en-us/vba/outlook-vba/articles/syncobject-syncstart-event-outlook.

    If you use Add-in Express, see the SyncStart event of the ADXOutlookAppEvents component. Note that by default the component doesn’t trigger this event to prevent your users from running in the issue we described at https://social.msdn.microsoft.com/Forums/office/en-US/7a20664c-7650-4d61-9d5f-13f1d929a8cd/outlook-2013-automatic-sendreceive-doesnt-work-with-the-sample-addin-below?forum=outlookdev. To let the component intercept this event, see the HandleEvents property the component provides.

  • vanaja says:

    I want to add a macro code from the text file to the outlook 2010 using c#. I have done a search for it but didn’t get any solution. Kindly help me on an urgent basis.
    Thank you

  • Andrei Smolin (Add-in Express Team) says:

    Hello Vanaja,

    Please check https://stackoverflow.com/questions/34837006/excel-vba-add-code-to-sheet-module-programmatically and https://stackoverflow.com/questions/12221837/programmatically-adding-references-to-outlook-2010-in-vba. These show how to do this using VBA. In your C# code, you need to add a reference to Microsoft Visual Basic for Applications Extensibility 5.3 library and use objects/methods shown in these pages.

    This path only works if the ‘Trust access to the VBA project object model’ check box in Trust Center | Macro Settings is selected.

  • Luigi says:

    Hello,
    When defining SEND & RECEIVE groups, there is a check mark called “Include the selected account in this group”. If this option is not selected for any specific account, that account is ignored during the send and receive process…. Is there a way to set up this option programmatically from Excel? I want to be able to Check and Uncheck this option from VB.

    Thank you!

  • Andrei Smolin (Add-in Express Team) says:

    Hello Luidgi,

    The Outlook object model provides no way to achieve this. But have a look at https://docs.microsoft.com/en-us/office/vba/api/outlook.folder.inappfoldersyncobject.

Post a comment

Have any questions? Ask us right now!