ImapX – free for use .NET library
ImapX is an modern .NET 2.0 library for management of IMAP folders, supports SSL Connection and different IMAP formats, such as Gmail IMAP, AOL IMAP
Here is simple example of usage:
ImapX.ImapClient client = new ImapX.ImapClient("imap.gmail.com", 993, true);
bool result = false;
result = client.Connection();
if (result)
Console.WriteLine("@Connected");
result = client.LogIn(userName, userPassword);
if (result)
{
Console.WriteLine("@Logged in");
}
//Folder Collection
ImapX.FolderCollection folders = client.Folders;
//Create folder
client.CreateFolder("NEW FOLDER", false);
//Message collection 1st option
ImapX.MessageCollection messages = client.Folders["INBOX"].Search("ALL", true); //true - means all message parts will be received from server
//2nd option
foreach (ImapX.Message m in client.Folders["INBOX"].Messages)
{
m.Process();
List attachments = m.Attachments;
string textBody = m.TextBody.TextData;
string htmlBody = m.HtmlBody.TextData;
}
ImapX.Message msg = new ImapX.Message();
msg.Subject = "hello yahoo";
msg.From.Add(new ImapX.MailAddress(fromUserName, fromUserEmail));
msg.To.Add(new ImapX.MailAddress(toUserName, toUserEmail));
msg.HtmlBody.ContentType = "text/html";
msg.HtmlBody.TextData = "it is test message";
ImapX.Attachment atach = new ImapX.Attachment();
atach.FileName = attachmentPath;
msg.Attachments.Add(atach);
if (client.Folders["INBOX"].AppendMessage(msg))
{
Console.WriteLine("message has been appended to INBOX");
}
Feature list supported by library:
- Folder management
- Message management
- Message saving in IMAP folder (like Drafts on Gmail)
- SSL
- Custom IMAP server implementations (like Google and AOL)
- Full IMAP Search compatible
Features to be implemented during near future:
- Offline message storage/synchronization
In ZIP archive you will find actual dll to use and IMAP Search reference document, sorry no documentation at this moment.
Hopefully it will be usefull.
Feb 24, 2010 update:
We have fixed following issues:
- now we correctly support message flags (“DELETED”, “SEEN”, “ANSWERED”, “DRAFT”, “RECENT”) and custom flags
- correctly handling spaces in passwords (need to be tested more, please contact us if you’ll find an issues there)
There are code sample which allows to set message flags:
ImapX.MessageCollection messages = client.Folders["INBOX"].SubFolder["NEWFOLDER"].Search("ALL");
//get list of current message flags
List allFlags = messages[1].Flags;
//set fllag array of flags are in ImapFlags constants
messages[1].SetFlag(ImapX.ImapFlags.SEEN);
Feb 25, 2010 update:
Today we have released version 1.0.5 of the library
Fixed issues:
- now correctly handling different types of subjects from IMAP
March 4, 2010 update:
Today we have released version 1.0.6 of the library with a great performance improvements (up to 4 time faster)
Fixed issues:
- Now it’s possible to search for messages without auto-filling the body, header and other message properties. Added new bool parameter for Search method which indicates to fill properties or no
Here is code example
//result messages + process()
ImapX.MessageCollection messages = client.Folders["G01"].Search("ALL", true);
//result empty messages
ImapX.MessageCollection messages = client.Folders["G01"].Search("ALL", false);
//fill message header info
messages[1].ProcessHeader();
//fill message flags info
messages[1].ProcessFlags();
//fill message body info
messages[1].ProcessBody();
//fill all message info
messages[1].Process();
March 4, 2010 update:
We have updated library to 1.0.6.1 version. Fixed some minor bugs. Thanx to Dalibor.
March 25, 2010 update:
We have updated library to 1.0.6.3 version. Fixed some more minor bugs.
March 26, 2010 update:
We have updated library to 1.0.6.4 version. Added IsDebug property to ImapX.ImapClient
client.isDebug = true; // with this option , all requests and responses are print to Console window
April 14, 2010 update:
We have updated library to 1.1 version. Fixed bugs with message processing, users faced in previous releases.
Please note: if your are facing any problems with message body or if message has no content-type, you may find all body parts in BodyParts collection:
List<MessageContent> bodyParts = msg.BodyParts; //get body : string body = bodyParts[index].ContentStream;
Some users facing problems with different Subject/Body encodings. Please note – ImapX itself doesn’t decode subject/body automatically. For instance if you have subject encoded to BASE64 using UTF8 charset you have to do following techniques:
//preparing subject to be sent
string codedSubject = "=?UTF-8?B?" + Convert.ToBase64String(Encoding.UTF8.GetBytes(subject)) + "?=";
//decoding subject from received message
string decodedSubject = Encoding.UTF8.GetString(Convert.FromBase64String(CodedSubject.Split('?')[4]));
//decoding body from Base64/UTF8 :
string decodedBody = Encoding.UTF8.GetString(Convert.FromBase64String(msg.HtmlBody.TextData));
Thanks to all of users of ImapX. And thank you for you comments, your responses help us to develop better IMAP library.
April 27, 2010 update:
We have updated body processing, ImapX refused to consume some bodies produced by Outlook 2007. It’s fixed in 1.1.0.1 version
May 12, 2010 update:
Updated:
- Message parsers updated
- Fixed problems with special characters in folder names
- Added body part properties: BoundaryNames and PartHeaders
Example:MessageContent body = message.HtmlBody; body.BoundaryNames // name of boundary of this part body.PartHeaders // Collection headers of this part
July 7, 2010 update:
Updated:
- Message parsers updated
- Fixed problems with marking message as seen during processing
- Fixed attachments processing
If you’ll face problems with a message parsing then please use method GetAsString() of class Message. It will allow you to use custom parsers to parse a message
Download
-
[...] ImapX [...]
-
[...] am using this library IMAPX to get [...]
-
[...] ImapX – free for use .NET library | HelloWebApps (hellowebapps.com) [...]
-
[...] downloaded the ImapX library and I need know it is possible get email list using imapx? if not, what is the best quick [...]
-
[...] ImapX – is an modern .NET 2.0 library for management of IMAP folders, supports SSL Connection and different IMAP formats, such as Gmail IMAP, AOL IMAP (November 30, 2011) Like this:Like一番乗りで「Like」しませんか。 カテゴリー: .NET, C# Sample, programing パーマリンク ← Cancel a Task for Parallel Programing C# [...]



Hi . I can sucessfully login into mail exchange server but when i try to search message collection it gives following exception “Bad or not correct
search query” at “client.Folders["INBOX"].Search(“ALL”) “.
Any Idea how to solve this?
Hello Nabeel,
can you please post a code?
And, are you sure folder “INBOX” exists, probably it’s written in other letters case or something.
Hi Andriy Mykhaylyuk
Actually there was rights problems with my mail account on exchange server.After resolving that i worked for me.Thanx for your reply.
Thanks for this. 2 days search for a simple IMAP library ends here. just what I wanted.
I am getting “TOO MANY ARGUMENTS” error if the password has a spaces in it
Same is the case for all other IMAP libraries. Any idea?
Hello Shobanl,
Hm, strange thing, probably you are not escaping special characters, I’ll try it out and come back to you soon.
Also can you give me a sample code to mark a mail as read?
Shoban,
We have updated our library to support spaces in passwords and I have included code example which marks mail as read into article, check it out please and let me know if it works for you.
Wow! that was quick. Thank you very much.
Password issue is sorted out. But when I try to get the subject of a fwded message. All I get is “fwd:” Any idea?
I couldn’t see SetFlag(imapx.imapflag.ANSWERED);
I get SetFlag(string flag);
Will check it tomorrow
Shoban,
we have fixed issues with subject.
About Flags:
SetFlag has string parameter, because each IMAP server can have own flags, so we have to support that feature.
ImapX.ImapFlags is set of string constants for default flags, which you can use on any standart IMAP server
Thanks Andriy
How do I mark a mail as read? I tried the following code but does not work. Any idea?
m.SetFlag(ImapX.ImapFlags.ANSWERED.ToString());
Hello Shoban,
to mark e-mail message as read you have to run following code:
m.SetFlag(ImapX.ImapFlags.SEEN);
Thanks for the quick reply
No problem,
Does it works for you?
There seems to be few problems in library so please help on this.
This code will produce lower error (stacktrace):
…
iClient._client.Capability();
string[] pathElements = selectedNode.Tag.ToString().Split(‘.’);
Folder _folder = iClient.Folders[pathElements[0]];
for (int i = 1; i < pathElements.Length; i++)
{
_folder = _folder.SubFolder[pathElements[i]];
}
_folder.Select();
ImapX.MessageCollection messages = _folder.Search("ALL");
AND: _folder.Messages[1].Process() will result with the same error.
ERROR:
System.ArgumentOutOfRangeException was unhandled
Message="Length cannot be less than zero.\r\nParameter name: length"
Source="mscorlib"
ParamName="length"
StackTrace:
at System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
at System.String.Substring(Int32 startIndex, Int32 length)
at ImapX.ParseHelper.Address(String line)
at ImapX.ParseHelper.AddressCollection(String line)
at ImapX.Message.getMessageHeader(String path)
at ImapX.Message.Process()
at ImapX.Folder.Search(String path)
at ImapBrowser.Form1.treeView1_AfterSelect(Object sender, TreeViewEventArgs e) in D:\Projects\ImapBrowser\ImapBrowser\Form1.cs:line 93
at System.Windows.Forms.TreeView.OnAfterSelect(TreeViewEventArgs e)
at System.Windows.Forms.TreeView.TvnSelected(NMTREEVIEW* nmtv)
at System.Windows.Forms.TreeView.WmNotify(Message& m)
at System.Windows.Forms.TreeView.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.Control.SendMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.Control.ReflectMessageInternal(IntPtr hWnd, Message& m)
at System.Windows.Forms.Control.WmNotify(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
at System.Windows.Forms.Control.DefWndProc(Message& m)
at System.Windows.Forms.TreeView.WmMouseDown(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.TreeView.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at ImapBrowser.Program.Main() in D:\Projects\ImapBrowser\ImapBrowser\Program.cs:line 17
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Then:
It seems that for some reason Folder.Search(some_flag) will try to fetch and process all found messages (to build a list of processed messages probably) and it will do it in THREE steps; fetch headers, fetch body and fetch flags.
There seems to be few problems in library so please help on this.
This code will produce lower error (stacktrace):
…
iClient._client.Capability();
string[] pathElements = selectedNode.Tag.ToString().Split(‘.’);
Folder _folder = iClient.Folders[pathElements[0]];
for (int i = 1; i < pathElements.Length; i++)
{
_folder = _folder.SubFolder[pathElements[i]];
}
_folder.Select();
ImapX.MessageCollection messages = _folder.Search("ALL");
AND: _folder.Messages[1].Process() will result with the same error.
ERROR:
System.ArgumentOutOfRangeException was unhandled
Message="Length cannot be less than zero.\r\nParameter name: length"
Source="mscorlib"
ParamName="length"
StackTrace:
at System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
at System.String.Substring(Int32 startIndex, Int32 length)
at ImapX.ParseHelper.Address(String line)
at ImapX.ParseHelper.AddressCollection(String line)
at ImapX.Message.getMessageHeader(String path)
at ImapX.Message.Process()
at ImapX.Folder.Search(String path)
Then:
It seems that Folder.Search(some_flag) will try to fetch and process all found messages (to build a list of processed messages) and it will do it in THREE steps; fetch headers, fetch body and fetch flags. This will happen for every found message and if there is a lot (say hundred) messages – it takes forever to finish. Don't know why
I propose a method Folder.CountMessages(some_flag) which will return ONLY a number of found messages, not a whole message collection.
Thank you.
Hello Dalibor,
we have updated library, your issues should be fixed.
A: IMAP search returns id’s of messages so it’s impossible just to get count of found messages unless using GMail IMAP extensions, but we are going to support that in near feature. Yes, there are 3 needed steps to fill the message, it’s IMAP protocol
Thanx for your interest.
Hy, I see you implemented “partial” message filling (headers, body, flags) and process() will still do all steps behind scene if selected. Many if not all IMAP servers will allow for “FETCH 1 BODY[]” which will return WHOLE message “as is”; headers and body divided between by empty line. So, you could save one round-trip between client-server and FETCH only “BODY[]” and “FLAGS” when doing “ALL” process().
As of “Folder.CountMessages(some_flag)” – actually IMAP functionality will allow to implement this very easily; just by counting message numbers. See this (naked IMAP “talk” in folder “SELECTED” IMAP state):
a050 search RECENT
* SEARCH 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515
a050 OK Search completed
So, Folder.CountMessages(“RECENT”) should invoke code above and count returned message numbers – there is 13 of them
Keep up good work; this library saved me quite some time; tnx.
I think I have found why processing message headers fails sometimes.
It seems that it will fail on a header like this:
From: “Ivan Marek”
and I think that ” sign makes it go wrong. That is only relevant difference between mail that passes parsing and one that does not.
Error returned:
—————–
System.ArgumentOutOfRangeException was unhandled
Message=”Length cannot be less than zero.\r\nParameter name: length”
Source=”mscorlib”
ParamName=”length”
StackTrace:
at System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
at System.String.Substring(Int32 startIndex, Int32 length)
at ImapX.ParseHelper.Address(String line)
at ImapX.ParseHelper.AddressCollection(String line)
at ImapX.Message.getMessageHeader(String path)
at ImapX.Message.Process()
HTML formatting cut email part of suspicious header (mail address in <> brackets). Should have been
From: “Ivan Marek” <Ivan.Marek@domain.com>
Hello Dalibor, inside “< " and ">” signs
which one IMAP server you are using?
From: “Ivan Marek” – is not a valid header, but we’ll add more validations. Header should contains exact email address as
Dalibor,
ok we are cheking, will come back to you soon
I really like the library. It is very easy to use. However, I am having a problem with getting the body of some messages. I am downloading messages from a gmail account. when some come across the the body shows up the way it should but on others neither the textbody htmlbody have the message in them. Any help would be much appreciated.
Sorry. The emails that I am not getting the body of are being sent as html.
Hello Eddie,
I’ve sent email to you with new build, please try it.
Hi, first of all I gotta say that you’re library looks pretty neat, and also it’s great to finally find an imap library that’s supported
I also have a question to ask, not really sure what’s going on in here with my testapp :
ImapX.ImapClient client = new ImapX.ImapClient(host, 143, false);
client.Connection();
client.LogIn(username, password);
ImapX.FolderCollection fc = client.GetFolders();
GetFolders() will give me an exception :
StartIndex cannot be less than zero.
Parameter name: startIndex
System.ArgumentOutOfRangeException: StartIndex cannot be less than zero.
Parameter name: startIndex
at System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
at System.String.Substring(Int32 startIndex)
at ImapX.Imap.GetFolders(String parent)
at ImapX.ImapClient.GetFolders()
at WindowsApplication1.Form1.button1_Click(Object sender, EventArgs e) in c:\foo\WindowsApplication1\WindowsApplication1\Form1.cs:line 40
My mailbox is fully functional, I can send and receive mail with other programs.
Hello Morri,
Thanx, we are doing our best for IMAPX library
We have updated IMAPX, so now your problem should be fixed, please download new version.
And one more note, get folders collection you have to use following construction:
ImapX.FolderCollection folders = client.Folders;
Thanks Andriy, the problem is gone in the new version, great job!
Message.Process() marks the message as seen, would it be possible to change this behaviour? I’d really like to control when my messages have their flags set.
Hello Morri,
We are not adding any flags to message on Process().
Most IMAP servers marks messages as seen in case there are other flags. Unseen is message without flags.
Hello,
I need to either move or delete messages after I have read them. I’ve tried the 3 following ways with no luck. Any ideas? Thank you.
client.Folders["Gmail]“].SubFolder["Spam"].MoveMessageToFolder(message, client.Folders["[Gmail]“].SubFolder["Trash"]);
client.Folders["[Gmail]“].SubFolder["Spam"].DeleteMessage(message);
message.SetFlag(ImapX.ImapFlags.DELETED);
message.ProcessFlags();
Hello Kenyon, please try following code:
ImapX.Message msg = client.Folders["Folder"].SubFolder["SubFolder"].Messages[index];
client.Folders["Folder"].SubFolder["SubFolder"].Select();
//or
client._client.SelectFolder(“Folder/Subfolder”);
ArrayList resultat = new ArrayList();
if (client._client.SendAndReceive(Command.STORE + ” ” + msg.MessageUid + ” + FLAGS (\\deleted)” + “\r\n”, ref resultat))
{
Console.WriteLine(“Message deleted”);
}
else
{
Console.WriteLine(“Error”);
}
I downloaded the latest version ImapX_1.0.6.4 and played with it the whole day.
I test with gmail with a few accounts, I found 2 problems:
1. Mime Encoded subject : if the email’s subject contains European characters, you would get something like this…
=?windows-1252?Q?Benachrichtigung_=FCber_Zahlungseingang?=
2. Cannot get TextBody.TextDate or HtmlBody.TextData , both are always NULL
Hi!
As everyone says, thanks for the library, your work is really appreciated
But as Eddie commented some days ago, I can’t seem to get the body of emails. I can see subject, etc, but not the body. I’ll be happy to try anything you want.
As a side note, it’d be cool to update the code at the beginning of the web, as it’s outdated now, and it’s the first thing to read:
ImapX.MessageCollection messages = client.Folders["INBOX"].Search(“ALL”);
it’s deprecated, boolean needs to be added
Thanks a lot!
I’ve run into 2 bugs –
1) like Roger, I am not always able to get the body of the message – I’ve seen this today on a message with the header: [Content-Type, multipart/alternative]. When I switch the client.Debug = true flag, I can see the message body in my “Immediate Window” in Visual Studio 2008. So although the body is being retrieved over IMAP, there doesn’t appear to be a way to access it in code.
2) If a message doesn’t have a content type header, the ImapX dll throws a NullReferenceException. I’m seeing it in getMessageBody(string path) method at if (this.ContentType.ToLower().Contains(“text/html”)), because this.ContentType is null (therefore, there is nothing “ToLower”). This prevents me from using message[index].Process(), message[index].ProcessBody(), and ImapX.MessageCollection messages = client.Folders["INBOX"].Search(“ALL”,true); (using “false” still works, since it doesn’t call Process()).
Hello Jared, Roger, Alan,
thanks for you interest, we are working on new build (should be delivered tomorrow) which will fix your problems
hi,
Thanks, I am considering using this library for an open source project.
Does the library support SASL with IMAP (a requirement for me) ?
-Anirudh
Hello Anirudh,
Unfortunately ImapX doesn’t support SASL yet. But we can collaborate with you or some other developers to add SASL support.
Hi,
I’m having the same issue with the 1.1 dll provided above that Jared, Roger and Alan were having (the body is alway empty when the type is multipart/alternative; (this is coming from Outlook 2007 if that makes a difference).
Works fine with plain text from outlook & web based clients.
Hi,
I have problems with the german letters: ö, ä, ü,Ü, Ö,Ä, and ß
I can’t login if the password includes one of this letters
and also Folder names with this letters (e.g. “Entwürfe” (wich is the folder “Drafts” in English)) look strange…
Hello, Sean, Jared, Roger and Alan
Looks like we fixed issue with bodies produced by Outlook 2007 in version 1.1.0.1 of ImapX, please try it.
Hello, Max,
your request is in queue, we’ll check everything tomorrow.
Andriy, the new DLL works great! Thanks!
works on my site too. Only problem is that for some emails it takes a whole clock-minute to ProcessBody. ProcessFlags and Header is fast, but ProcessBody can take up to 1.30min on some emails…
anyway, your work is highly apreciated, thanks a lot
Roger, please check Debug is disabled in ImapX client. Debug property slows down everything.
It is disabled. As I said it only happens with some emails (for example, with the one I forwarded to you)
I have been having great luck with the 1.1.0.1 version – thanks! I find it to be much quicker at processing messages than before.
Does ImapX support the IDLE command? http://tools.ietf.org/html/rfc2177
Hi..I am having the same problem Kenyon had above…I can’t move a message from one folder to another. I am connecting to Gmail…
ImapX.Folder inbox = client.Folders["INBOX"];
ImapX.Folder downloaded = client.Folders["Complete"];
ImapX.MessageCollection messages = inbox.Search(“ALL”, true);
foreach (ImapX.Message message in messages)
{
inbox.MoveMessageToFolder(message, downloaded);
}
The “Complete” folder does exist and when I check the properties of it, I can access it’s name, folderpath,exists….
The error I get is “Object reference not set to an instance of an object.”
I should note that when I run this in a console application, if I keep hitting run after I get the exception, eventually it will work….
Also, CopyMessageToFolder gives me the same error, but it does actually copy the message.
Any ideas on what I am doing wrong? I am using version 1.1.0.1.
Hey there..I love this library..It’s so easy to work with, but I think i found another bug… When dealing with attachments, the FileName of the attachment is always null.