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!

14 Comments

  • http://0.gravatar.com/avatar/259385e0107c52497f03804de478a6b9?s=32&d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G makopung primary says:

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

  • 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.

  • http://1.gravatar.com/avatar/31c4346f121e0b05eb80176d9f302397?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G 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

  • Hi Jaideep,

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

  • http://1.gravatar.com/avatar/31c4346f121e0b05eb80176d9f302397?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G 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

  • 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.

  • http://1.gravatar.com/avatar/31c4346f121e0b05eb80176d9f302397?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G 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.

  • 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?

  • http://1.gravatar.com/avatar/31c4346f121e0b05eb80176d9f302397?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G 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.

  • http://1.gravatar.com/avatar/f823d9de5ccbbd18d1ed753dd53fd5ac?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G Patrick Ellis says:

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

  • Hi Patrick,

    Thank you for the kind words ;-)

  • http://1.gravatar.com/avatar/17f081e6a65caa51039013b3c3e89fb4?s=32&d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D32&r=G 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();
    }

  • 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.

Post a comment

Have any questions? Ask us right now!