I have problems issuing IMAP, POP3 or SMTP command

Mail.dll is a rock solid product, however most email servers don’t follow RFC specifications rigorously. In the following few steps we’ll help you gather the information we need to make Mail.dll IMAP and POP3 clients better.

If you have problems parsing a message please go here.

Prerequisites

First please check if you have the latest version installed. You can always download the latest version of Mail.dll email component and release notes here.

Identify command

Please identify the command/set of commands that cause problems.

Turn on logging

Enable logging for Mail.dll clients:

// C# version:

Log.Enabled = true;

' VB.NET version:

Log.Enabled = True

You can observe standard Visual Studio’s trace output window (View/Output/Show output from: Debug) or add a custom listener to Trace.Listeners collection.

You can also enable logging using App.config file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.diagnostics>
      <switches>
        <add name="Mail.dll" value="True" />
      </switches>
    </system.diagnostics>
</configuration>

log4net

If you are using the latest version of log4net.dll, Mail.dll is going to use log4net instead of Trace class. Please refer to log4net manual on how to capture log entries.

Please remember that even when using log4net, you need to enable logging by setting “Limilabs.Mail.Log.Enabled = True” or be setting Mail.dll boolean switch in App.config file.

Log to file

You can create your custom TraceListener that writes log to file:

// C# version:

internal class MyListener : TextWriterTraceListener
{
    public MyListener(string fileName)
        : base(fileName)
    {
    }

    public override void Write(string message, string category)
    {
        if (category == "Mail.dll")
            base.Write(message, category);
    }

    public override void WriteLine(string message, string category)
    {
        if (category == "Mail.dll")
            base.WriteLine(message, category);
    }
}
' VB.NET version

Friend Class MyListener
	Inherits TextWriterTraceListener
	Public Sub New(fileName As String)
		MyBase.New(fileName)
	End Sub

	Public Overrides Sub Write(message As String, category As String)
		If category = "Mail.dll" Then
			MyBase.Write(message, category)
		End If
	End Sub

	Public Overrides Sub WriteLine(message As String, category As String)
		If category = "Mail.dll" Then
			MyBase.WriteLine(message, category)
		End If
	End Sub
End Class

…then add it to Listeners collection:

// C# version:

Log.Enabled = true;
Trace.Listeners.Add(new MyListener(@"c:/mail_log.txt"));
Trace.AutoFlush = true;

' VB.NET version:

Log.Enabled = True
Trace.Listeners.Add(New MyListener("c:/mail_log.txt"))
Trace.AutoFlush = True

Log.WriteLine

Log class exposes WriteLine event. You can use that event to subscribe your own logging library:

// C#

Log.WriteLine += Console.WriteLine;
' VB.NET

Log.WriteLine += Console.WriteLine

Reproduce the problem

Perform the operations that cause problems, and save the log to file.
You can remove username and password, but please do not modify the file extensively. If you do, it may be impossible to reproduce the issue.
In particular do not change new line format nor encoding.

Additional information

Please answer following questions:

  • What exception are you getting?
  • What is the exception stack trace?
  • What is the exception message?
  • What result you expect?
  • What result are you getting?
  • Which .NET Framework version are you using?
  • Is it console, windows forms, windows service or web application?
  • If it is possible please attach the source code you are using

Contact Limilabs support 

Finally please zip the log file and send it as an attachment, along with all the answers to: .

Thank you!

I have problems parsing the message

Mail.dll is a rock solid product, however most emails don’t follow RFC specifications rigorously. In the following few steps we’ll help you gather the information we need to make Mail.dll parser better.

If you have problems issuing IMAP, POP3, or SMTP command please go here.

Prerequisites

First please check if you have the latest version of Mail.dll installed. You can always download the latest version of Mail.dll email component and check release notes here.

Identify UID

Please identify unique id (UID) of the message you are having problems with.

Download email

Next step is to download entire email message and save it as a raw eml file.
Note that you should not parse the email, so there is no need to use MailBuilder and IMail classes.

Download using IMAP protocol

// C# code

long uid = 12345;

using (Imap imap = new Imap())
{
    imap.ConnectSSL("imap.example.com"); 
    imap.UseBestLogin("user";, "password");
    imap.SelectInbox();

    byte[] eml = imap.GetMessageByUID(uid);
    string fileName = string.Format(@"c:\email_{0}.eml", uid);
    File.WriteAllBytes(fileName, eml);

    imap.Close();
}
' VB.NET code

Dim uid As Long = 12345

Using imap As New Imap()
	imap.ConnectSSL("imap.example.com") 
	imap.UseBestLogin("user", "password")
	imap.SelectInbox()

	Dim eml As Byte() = imap.GetMessageByUID(uid)
	Dim fileName As String = String.Format("c:\email_{0}.eml", uid)
	File.WriteAllBytes(fileName, eml))

	imap.Close()
End Using

Download using POP3 protocol

// C# code

string uid = "12345";

using (Pop3 pop3 = new Pop3())
{
    pop3.ConnectSSL("pop3.example.com");
    pop3.UseBestLogin("user", "password");

    byte[] eml = pop3.GetMessageByUID(uid));
    string fileName = string.Format(@"c:\email_{0}.eml", uid);
    File.WriteAllBytes(fileName, eml);

    pop3.Close();
}
' VB.NET code

Dim uid As String = "12345";

Using pop3 As New Pop3()
	pop3.ConnectSSL("pop3.example.com")
	pop3.UseBestLogin("user", "password")

	Dim eml As Byte() = pop3.GetMessageByUID(uid)
	Dim fileName As String = String.Format("c:\email_{0}.eml", uid)
	File.WriteAllBytes(fileName, eml)

	pop3.Close()
End Using

Additional information

Please answer following questions:

  • What exception are you getting?
  • What is the exception stack trace?
  • What is the exception message?
  • What result do you expect?
  • What result are you getting?
  • Which .NET Framework version are you using?
  • Is it console, windows forms, windows service or web application?
  • If it is possible please attach the source code you are using

Contact Limilabs support 

Finally please zip the eml file and send it as an attachment along with all answers to: .

Thank you!

Send iCalendar recurring meeting requests

First add all necessary namespaces:

// C# version

using System;
using Limilabs.Mail;
using Limilabs.Mail.Appointments;
using Limilabs.Mail.Headers;
using Fluent = Limilabs.Mail.Fluent;
using Limilabs.Client.SMTP;
' VB.NET version

Imports System;
Imports Limilabs.Mail;
Imports Limilabs.Mail.Appointments;
Imports Limilabs.Mail.Headers;
Imports Fluent = Limilabs.Mail.Fluent;
Imports Limilabs.Client.SMTP;

Now, we’ll create an appointment, specify it’s recurring options and send it:

// C# version

Appointment appointment = new Appointment();
Event newEvent = appointment.AddEvent();
newEvent.SetOrganizer(new Person("Alice", "alice@example.org"));
newEvent.AddParticipant(new Participant("Bob", "bob@gmail.com"));
newEvent.Description = "We need to talk about the daily report";
newEvent.Summary = "Daily report meeting";
newEvent.Start = new DateTime(2010, 11, 29, 16, 0, 0);
newEvent.End = new DateTime(2010, 11, 29, 17, 0, 0);
newEvent.Priority = 5;
newEvent.Class = EventClass.Public;

RecurringRule rule = newEvent.AddRecurringRule();
rule.Interval = 1;
rule.Until = new DateTime(2011, 12, 1); // -or- rule.Count = 10;

// Every week on  Mon, Tue, Wed, Thu Fri:
rule.Frequency = Frequency.Weekly;
rule.ByDay.AddRange(new[] {
    Weekday.Monday,
    Weekday.Tuesday,
    Weekday.Wednesday,
    Weekday.Thursday,
    Weekday.Friday });

Alarm alarm = newEvent.AddAlarm();
alarm.Description = "Reminder";
alarm.BeforeStart(TimeSpan.FromMinutes(5));

IMail email = Fluent.Mail.Text("Daily report meeting at 4PM")
    .Subject("Daily report meeting")
    .From(new MailBox("alice@example.org", "Alice"))
    .To(new MailBox("bob@example.org", "Bob"))
    .AddAppointment(appointment)
    .Create();

using (Smtp client = new Smtp())
{
    client.ConnectSSL("smtp.example.org");
    client.UseBestLogin("user", "password");
    client.SendMessage(email);
    client.Close();
}
' VB.NET version

Dim appointment As New Appointment()
Dim newEvent As [Event] = appointment.AddEvent()
newEvent.SetOrganizer(New Person("Alice", "alice@example.org"))
newEvent.AddParticipant(New Participant("Bob", "bob@gmail.com"))
newEvent.Description = "We need to talk about the daily report"
newEvent.Summary = "Daily report meeting"
newEvent.Start = New DateTime(2010, 11, 29, 16, 0, 0)
newEvent.[End] = New DateTime(2010, 11, 29, 17, 0, 0)
newEvent.Priority = 5
newEvent.[Class] = EventClass.[Public]

Dim rule As RecurringRule = newEvent.AddRecurringRule()
rule.Interval = 1
rule.Until = New DateTime(2011, 12, 1)
' -or- rule.Count = 10;
' Every week on  Mon, Tue, Wed, Thu Fri:
rule.Frequency = Frequency.Weekly
rule.ByDay.AddRange(New Weekday() {Weekday.Monday _
                                   , Weekday.Tuesday _
                                   , Weekday.Wednesday _
                                   , Weekday.Thursday _
                                   , Weekday.Friday})

Dim alarm As Alarm = newEvent.AddAlarm()
alarm.Description = "Reminder"
alarm.BeforeStart(TimeSpan.FromMinutes(5))

Dim email As IMail = Fluent.Mail.Text("Daily report meeting at 4PM") _
    .Subject("Daily report meeting") _
    .From(New MailBox("alice@example.org", "Alice")) _
    .[To](New MailBox("bob@example.org", "Bob")) _
    .AddAppointment(appointment).Create()

Using client As New Smtp()
    client.ConnectSSL("smtp.example.org")
    client.UseBestLogin("user", "password")
    client.SendMessage(email)
    client.Close()
End Using

This is how it looks like in Gmail:

Recurring appointment

Recurring meeting frequency

Here are the few samples of how you can set the frequency:

Daily:

// C# version

rule.Frequency = Frequency.Daily;
' VB.NET version

rule.Frequency = Frequency.Daily

Every month on last monday:

// C# version

rule.Frequency = Frequency.Monthly;
rule.ByDay.Add(Weekday.LastMonday);
' VB.NET version

rule.Frequency = Frequency.Monthly
rule.ByDay.Add(Weekday.LastMonday)

Every month on second but last monday:

// C# version

rule.Frequency = Frequency.Monthly;
rule.ByDay.Add(new Weekday(-2, Weekday.Monday));
' VB.NET version

rule.Frequency = Frequency.Monthly
rule.ByDay.Add(New Weekday(-2, Weekday.Monday))

Verify file hash after FTP upload

This blog post describes hot to check the file checksum (hash) after upload to FTP server. Ftp.dll .NET FTP component supports most popular hashing algorithms like CRC, MD5 and SHA1.

First add appropriate namespaces:

// C# version

using Limilabs.FTP.Client;
using Limilabs.FTP.Client.Hash;

' VB.NET version

Imports Limilabs.FTP.Client
Imports Limilabs.FTP.Client.Hash

Then upload the file, ask the server for hash of the uploaded file, compute the local hash and compare them:

// C# version

using (Ftp client = new Ftp())
{
    client.Connect("ftp.example.org");
    client.Login("user", "password");

    client.Upload("report.txt", @"c:\report.txt");

    byte[] serverHash = client.GetFileHash(
        "report.txt",
        FtpHashType.CRC);

    FileHash hash = new FileHash(FtpHashType.CRC);
    bool hashIsValid = hash.IsValid(@"c:\report.txt", serverHash);

    Console.WriteLine(hashIsValid);

    client.Close();
}
' VB.NET version

Using client As New Ftp()
	client.Connect("ftp.example.org")
	client.Login("user", "password")

	client.Upload("report.txt", "c:\report.txt")

	Dim serverHash As Byte() = client.GetFileHash( _
		"report.txt", _
		FtpHashType.CRC)

	Dim hash As New FileHash(FtpHashType.CRC)
	Dim hashIsValid As Boolean = hash.IsValid("c:\report.txt", serverHash)

	Console.WriteLine(hashIsValid)

	client.Close()
End Using

You can use CRC, MD5 and SHA1 algorithms for hash verification.

You can download Ftp.dll FTP/FTPS client for .NET here.

Verify file hash after FTP download

This blog post describes how to check the file checksum (hash) after downloading the file from FTP server. Ftp.dll .NET FTP component supports most popular hashing algorithms (CRC, MD5 and SHA1).

First add appropriate namespaces:

// C# version

using Limilabs.FTP.Client;
using Limilabs.FTP.Client.Hash;

' VB.NET version

Imports Limilabs.FTP.Client
Imports Limilabs.FTP.Client.Hash

Then download the file, ask server for its hash, compute the local hash and compare them:

// C# version

using (Ftp client = new Ftp())
{
    client.Connect("ftp.example.org");
    client.Login("user", "password");

    client.Download("report.txt", @"c:\report.txt");

    byte[] serverHash = client.GetFileHash(
        "report.txt",
        FtpHashType.CRC);

    FileHash hash = new FileHash(FtpHashType.CRC);
    bool hashIsValid = hash.IsValid(@"c:\report.txt", serverHash);

    Console.WriteLine(hashIsValid);

    client.Close();
}
' VB.NET version

Using client As New Ftp()
	client.Connect("ftp.example.org")
	client.Login("user", "password")

	client.Download("report.txt", "c:\report.txt")

	Dim serverHash As Byte() = client.GetFileHash( _
		"report.txt", _
		FtpHashType.CRC)

	Dim hash As New FileHash(FtpHashType.CRC)
	Dim hashIsValid As Boolean = hash.IsValid("c:\report.txt", serverHash)

	Console.WriteLine(hashIsValid)

	client.Close()
End Using

You can use CRC, MD5 and SHA1 algorithms for hash verification.

You can download Ftp.dll FTP/FTPS client for .NET here.