- Vmime.NET_All.rar (9 MB): The entire project with all files required to compile for 32 Bit platform.
- Vmime.NET_64.rar (6 MB): Only a few additional files required to compile for 64 Bit platform.
With this project, C++ and .NET Windows programmers get a very versatile library to send and download emails via SMTP, POP3 and IMAP with TLS and SSL support.
- This is a high quality library that can be used in production.
- SMTP, POP3, IMAP protocols implemented.
- TLS and SSL encrpyption (using openssl library) with 185 built-in X.509 root certificates.
- SASL authentication (Simple Authentication and Security Layer).
- Email builder builds RFC-2822 and multipart messages.
- HTML email generation with embedded objects.
- Full support for attachments with automatic mime-type detection of 1010 built-in mime types.
- Email parser allows to extract attachments or text.
- You will learn in 15 minutes how to use the library. It follows the KISS principle ("Keep it simple, stupid").
- This project is mainly written in pure C++ and has a manged C++ wrapper that exposes the functionality to .NET (C# and Visual Basic .NET).
- Fully RFC-compliant implementation.
- 8-bit MIME, encoded word extensions, pipelining and chunked message transfer.
- Trace output showing the entire communication with the server.
- Full Unicode support for CJK (Chinese, Japanese, Korean).
- Very clean code written by very experienced programmers.
- Demo application in C++.
- Demo application in C#.
- All required dependencies (e.g. openssl) are included in the download. You don’t have to download other sources to compile the project.
- The download contains vmime.NET_2.dll for .NET framework 2.0, 3.0, 3.5.
- The download contains vmime.NET_4.dll for .NET framework 4.0, 4.5, 4.6., etc..
- The second download contains the 64 Bit version of each of them.
- The DLL is strong named (signed).
- GNU GPL license. (Commercial licenses available)
- Update february 2016: Now the project compiles without the deprecated compiler switch ‘/clr:oldsyntax’.
Why using vmime ?
I was searching for a SMTP/POP3/IMAP library. What I found were either very expensive commercial libraries or free libraries without encryption support. Today many SMTP servers demand a TLS or SSL connection. With an email library that does not support encryption you will not be able to send an email to a Gmail SMTP server.
Finally I found vmime, which is a multi platform library for SMTP, POP3, IMAP, SendMail and MailDir with very cleanly written code and hosted on Github, mainly written by Vincent Richard, who did a great work.
A nightmare begins…
But this library is a Gnu project that was developed and tested mainly in the Mac / Linux world. Theoretically it should be possible to compile it on Windows with the Cmake compiler, but that threw a lot of cryptic error messages that I never saw before, so I gave up.
Additionally CMake is useless if you want to write a Managed C++ project for .NET. So I had to find a way to compile this stuff on Visual Studio. If you ever ported code from Linux to Windows you know what nightmare this is.
After eliminating all the errors in Visual Studio that you see whenever you compile a Linux project on Windows, I had the problem that the Config.hpp file was missing which contains all the project settings. I had to find out how to construct this file manually.
Then vmime depends on several other Gnu projects which I had to download separately:
- GnuTLS or OpenSSL library for encryption,
- iconv, a character set converter library,
- gsasl, an authentication libary
All these libraries exist precompiled for Windows as DLLs and come with a Lib file for the linker. Some of them come with library files with names like "libgsasl.a". I never saw this file extension before and thought: These files are made for Windows so I change that to "libgsasl.lib". And the worst of all is that Visual Studio eats these files without complaining. But the compiled binary file will not run.
Finally I found out that these *.a files are for a Gnu compiler on Windows.
And where do I find the Lib files for Visual Studio?
They simply do not exist.
After investigating I found that I can create the Lib file from the Def file with a Visual Studio command line tool. See "libvmime\src\gsasl\CreateLIB.bat"
I started my first tests with GnuTLS which was an error, because:
- GnuTLS depends on 4 more libraries (total 5 DLL’s!)
- None of these DLLs exists as 64 Bit version
- It does not run correctly on Windows (throws Error "The TLS connection was non properly terminated" in the middle of an email transfer)
I wasted a lot of time with this library, finally I moved to OpenSSL which works perfectly.
The iconv library also caused me problems because there is no precompiled 64 Bit version for Windows and this library has apparently never been compiled for 64 Bit. Finally I replaced it with my own code that uses the Windows Codepage conversion API instead.
Problems with vmime
Then I started struggling with vmime code itself:
A severe lack was that vmime had no Unicode support. All strings are std::string while std::wstring was used in no place. Filenames were translated with the current ANSI codepage and passed to the ANSI file API (e.g. CreateFileA).
To permit that vmime can also be used by chinese or japanese users I had to find a way to pass unicode into vmime. I ended up converting all input strings in a wrapper class into UTF-8. Then, in the windows platform handler I convert the UTF-8 strings back to Unicode and pass them to widechar API (CreateFileW).
Another severe lack of vmime was the missing Trace output. When an error occurred with the server you had no idea what was the reason because you did not see the communication with the server. I implemented Trace support as you see in the screenshots below.
Another lack was that vmime code was not abortable. If the server did not respond the user had to wait until the timeout elapsed – up to 30 seconds! I fixed that.
Another problem was that in vmime error handling was not properly implemented.
Then I found several bugs, like for example openssl throwing "SSL3_WRITE_PENDING:bad write retry". I contacted Vincent – the author of vmime – who gave me excellent support with all problems and fixed some of these bugs.
Then I added new features that are indispensable for an easy usage like automatic mime type detection by file extension and loading root certificates from the resources.
The vmime library has been designed to be very flexible and expandable. This is good but has the disadvantage that the usage becomes awkward
. For a simple task like extracting the plain text of an email you have to write a loop, enumerate all message parts, use a MessageParser, use a OutputStreamStringAdapter, a ContentHandler, a SmartPointer class, dynamic casts and character set conversion. All this is clumsy and an experienced programmer – new to vmime – easily needs some hours to find out how to do this. And for C++ beginners it will be nearly impossible to use vmime.
So I added wrapper classes
that hide all this complicated stuff in a single function. (KISS principle
Then I discovered a VERY weird phenomenon: Whenever in vmime an exception was thrown, I had memory leaks
and TCP sockets that were not closed because several destructors were never called (no stack unwinding). You can read on Stackoverfow
how I solved this.
I did a lot more things but to mention all this would be too much here…..
All my changes in the source code are marked with a comment: // FIX by Elmue , if you search so you find more than 240 modifications.
…finally I was working two months on this project. I did really frustrating work and I nearly gave up more than once.
Now you are in the fortunate situation, that you can download a ready-to-use library that works perfectly and is very easy to use and intuitive.
With very few lines of code you can create a mime email with a plain text part, a Html part, embedded Html objects (e.g. images) and attachments. Both, plain text and Html text are optional. Modern email clients do not display the plain text part if a Html part is present.