More .NET components

IMAP - folder operations

The sample code on this page assumes you have already connected and authenticated to an IMAP servers.

Setting and getting current folder #

An IMAP mailbox can contain lot of folders at various level of hierarchy. However, you can always find an Inbox folder. Before working with messages in a specific folder, you have to specify a current working folder first for most IMAP commands.

  • To set a working folder, use the SelectFolder method.
  • To unset a working folder, use the UnselectFolder method (optional).
  • To get the current working folder, use the CurrentFolder property.

CSharp

// create IMAP client instance, connect, log in
var imap = new Rebex.Net.Imap();
imap.Connect(hostname, SslMode.Implicit);
imap.Login(username, password);

// set Inbox as working folder
imap.SelectFolder("Inbox");

// print info about current working folder
ImapFolder info = imap.CurrentFolder;
Console.WriteLine("Working folder: {0}", info.Name);
Console.WriteLine("Total messages: {0}", info.TotalMessageCount);
Console.WriteLine("Not-seen messages: {0}", info.NotSeenMessageCount);

// unselect folder
imap.UnselectFolder();

VisualBasic

' create IMAP client instance, connect, log in
Dim imap As New Rebex.Net.Imap()
imap.Connect(hostname, SslMode.Implicit)
imap.Login(username, password)

' set Inbox as working folder
imap.SelectFolder("Inbox")

' print info about current working folder
Dim info As ImapFolder = imap.CurrentFolder
Console.WriteLine("Working folder: {0}", info.Name)
Console.WriteLine("Total messages: {0}", info.TotalMessageCount)
Console.WriteLine("Not-seen messages: {0}", info.NotSeenMessageCount)

' unselect folder
imap.UnselectFolder()

Getting folder info #

There are several ways to retrieve information about an IMAP folder:

  • Imap object's CurrentFolder property provides information about the current working folder.
  • GetFolderInfo method retrieves information about the specified folder.
  • GetFolderList method lists available folders.

All of these methods and properties provide an instance (or list) of ImapFolder objects. However, not all of them provide all the information. Please see the description of specific ImapFolder property to determine when it is available.

CSharp

// create IMAP client instance, connect, log in
// ...

// print info about Inbox
ImapFolder info = imap.GetFolderInfo("Inbox");
Console.WriteLine("Folder: {0}", info.Name);
Console.WriteLine("Total messages: {0}", info.TotalMessageCount);
Console.WriteLine("Not-seen messages: {0}", info.NotSeenMessageCount);

VisualBasic

' create IMAP client instance, connect, log in
' ...

' print info about Inbox
Dim info As ImapFolder = imap.GetFolderInfo("Inbox")
Console.WriteLine("Folder: {0}", info.Name)
Console.WriteLine("Total messages: {0}", info.TotalMessageCount)
Console.WriteLine("Not-seen messages: {0}", info.NotSeenMessageCount)

Getting list of folders #

To get list of folders in a mailbox, use the GetFolderList method.

CSharp

// create IMAP client instance, connect, log in
// ...

// get the root folders
ImapFolderCollection rootFolders = imap.GetFolderList();

// get all folders
ImapFolderCollection allFolders = imap.GetFolderList("", ImapFolderListMode.All, true);

VisualBasic

' create IMAP client instance, connect, log in
' ...

' get the root folders
Dim rootFolders As ImapFolderCollection = imap.GetFolderList()

' get all folders
Dim allFolders As ImapFolderCollection = imap.GetFolderList("", ImapFolderListMode.All, True)

Please note that the ImapFolder objects returned by this method don't provide as much information as those returned by GetFolderInfo. See the description of specific ImapFolder property to determine when it is available.

Subscribing to a folder #

IMAP protocol enables you to mark folders as subscribed, speeding up listing of them later (by ignoring non-subscribed folders).

CSharp

// create IMAP client instance, connect, log in
// ...

// subscribe some folders
imap.Subscribe("Inbox");
imap.Subscribe("Outbox");

// list all subscribed folders
ImapFolderCollection list = imap.GetFolderList("", ImapFolderListMode.Subscribed, true);
foreach (ImapFolder folder in list)
{
    // get richer info for folder and print it
    ImapFolder info = imap.GetFolderInfo(folder.Name);
    Console.WriteLine("Folder: {0}", info.Name);
    Console.WriteLine("Total messages: {0}", info.TotalMessageCount);
    Console.WriteLine("Not-seen messages: {0}", info.NotSeenMessageCount);
}

// unsubscribe some folders
imap.Unsubscribe("Outbox");

VisualBasic

' create IMAP client instance, connect, log in
' ...

' subscribe some folders
imap.Subscribe("Inbox")
imap.Subscribe("Outbox")

' list all subscribed folders
Dim list As ImapFolderCollection = imap.GetFolderList("", ImapFolderListMode.Subscribed, True)
For Each folder As ImapFolder In list
    ' get richer info for folder and print it
    Dim info As ImapFolder = imap.GetFolderInfo(folder.Name)
    Console.WriteLine("Folder: {0}", info.Name)
    Console.WriteLine("Total messages: {0}", info.TotalMessageCount)
    Console.WriteLine("Not-seen messages: {0}", info.NotSeenMessageCount)
Next

' unsubscribe some folders
imap.Unsubscribe("Outbox")

Checking folder existence #

To determine whether a folder exists, use the FolderExists method.

CSharp

// create IMAP client instance, connect, log in
// ...

// check if "My mails" folder exists
bool exists = imap.FolderExists("My mails");

VisualBasic

' create IMAP client instance, connect, log in
' ...

' check if "My mails" folder exists
Dim exists As Boolean = imap.FolderExists("My mails")

Creating and removing folders #

Most IMAP servers let you create or remove custom folders.

  • To create a folder, use the CreateFolder method.
  • To remove a folder, use the DeleteFolder method.

CSharp

// create IMAP client instance, connect, log in
// ...

// create new "My mails" folder if doesn't exist
if (!imap.FolderExists("My mails"))
    imap.CreateFolder("My mails");

// remove "My e-mails" if exists
if (imap.FolderExists("My e-mails"))
    imap.DeleteFolder("My e-mails");

VisualBasic

' create IMAP client instance, connect, log in
' ...

' create new "My mails" folder if doesn't exist
If Not imap.FolderExists("My mails") Then
    imap.CreateFolder("My mails")
End If

' remove "My e-mails" if exists
If imap.FolderExists("My e-mails") Then
    imap.DeleteFolder("My e-mails")
End If

Renaming folders #

To rename a folder, use the RenameFolder method.

CSharp

// create IMAP client instance, connect, log in
// ...

string oldName = "My e-mails";
string newName = "My mails";

bool oldExists = imap.FolderExists(oldName);
bool newExists = imap.FolderExists(newName);

// rename folder "My e-mails" to "My mails"
if (oldExists && !newExists)
    imap.RenameFolder(oldName, newName);

VisualBasic

' create IMAP client instance, connect, log in
' ...

Dim oldName As String = "My e-mails"
Dim newName As String = "My mails"

Dim oldExists As Boolean = imap.FolderExists(oldName)
Dim newExists As Boolean = imap.FolderExists(newName)

' rename folder "My e-mails" to "My mails"
If oldExists AndAlso Not newExists Then
    imap.RenameFolder(oldName, newName)
End If

Getting list of changes #

IMAP servers notify connected clients of changes in the current working folder. For example, they inform clients when a new message arrives or when a message has been deleted. The client usually receives these notifications when reading server response to its command.

However, handling these notifications is a bit tricky. The most straightforward way of processing those notifications is to use a combination of Notification event and CheckForUpdates method.

The following code shows how to use the Notification event and CheckForUpdates method to implement simple one-way-synchronization. The program downloads all not-Read messages to a local directory and waits for server notifications in the meantime. When new mail arrives to the folder, it is downloaded immediately. When a mail is marked as not-Read (by one of the other sessions), it is downloaded again.

Note: This variant of CheckForUpdates utilizes IMAP IDLE extension when available.

CSharp

// create IMAP client instance, connect, log in, select desired folder
// ...

// register notification event
imap.Notification += imap_Notification;

// keep synchronization process running
while (!_stopped)
{
    // search for UNREAD mails
    ImapMessageCollection list =
        imap.Search(ImapListFields.UniqueId, ImapSearchParameter.Unread);

    // download all UNREAD mails
    foreach (ImapMessageInfo info in list)
    {
        // exit if stopped
        if (_stopped)
            return;

        // prepare path
        string path = string.Format(@"C:\MyData\{0}.eml", Guid.NewGuid());

        // download mail
        imap.GetMessage(info.UniqueId, path);
    }

    // keep waiting for server notifications
    while (!_syncNeeded && !_stopped)
    {
        // process server notifications in 5 minutes intervals
        imap.CheckForUpdates(5 * 60 * 1000);
    }

    // reset flag
    _syncNeeded = false;
}

VisualBasic

' create IMAP client instance, connect, log in, select desired folder
' ...

' register notification event
AddHandler imap.Notification, AddressOf imap_Notification

' keep synchronization process running
While Not _stopped
    ' search for UNREAD mails
    Dim list As ImapMessageCollection =
        imap.Search(ImapListFields.UniqueId, ImapSearchParameter.Unread)

    ' download all UNREAD mails
    For Each info As ImapMessageInfo In list
        ' exit if stopped
        If _stopped Then
            Return
        End If

        ' prepare path
        Dim path As String = String.Format("C:\MyData\{0}.eml", Guid.NewGuid())

        ' download mail
        imap.GetMessage(info.UniqueId, path)
    Next

    ' keep waiting for server notifications
    While Not _syncNeeded AndAlso Not _stopped
        ' process server notifications in 5 minutes intervals
        imap.CheckForUpdates(5 * 60 * 1000)
    End While

    ' reset flag
    _syncNeeded = False
End While

Event handler for the code above is following:

CSharp

// flag - whether to stop the synchronization process
bool _stopped;

// flag - whether the synchronization needs to be performed
bool _syncNeeded;

// Notification handler can be triggered by any Imap method
void imap_Notification(object sender, ImapNotificationEventArgs e)
{
    // for one-way-synchronization following values are relevant
    switch (e.Notification)
    {
        case ImapNotification.MessageCount:
        case ImapNotification.RecentMessages:
        case ImapNotification.MessageInfo:
            // set flag
            _syncNeeded = true;

            // abort current operation
            // we cannot perform any operation here,
            // because Imap object is still locked,
            // performing any operation will always fail
            // with ImapExceptionStatus.Pending
            var imap = sender as Imap;
            imap.Abort();
            break;
    }
}

VisualBasic

' flag - whether to stop the synchronization process
Private _stopped As Boolean

' flag - whether the synchronization needs to be performed
Private _syncNeeded As Boolean

' Notification handler can be triggered by any Imap method
Private Sub imap_Notification(sender As Object, e As ImapNotificationEventArgs)
    ' for one-way-synchronization following values are relevant
    Select Case e.Notification
        Case ImapNotification.MessageCount,
            ImapNotification.RecentMessages,
            ImapNotification.MessageInfo
            ' set flag
            _syncNeeded = True

            ' abort current operation
            ' we cannot perform any operation here,
            ' because Imap object is still locked,
            ' performing any operation will always fail
            ' with ImapExceptionStatus.Pending
            Dim imap = TryCast(sender, Imap)
            imap.Abort()
            Exit Select
    End Select
End Sub