Converting MSG to EML - Handles Exchange Addresses?

0 votes
asked Feb 26, 2011 by Josh Zacharias (150 points)
edited Jul 25, 2013

Is there a way to get the correct "From" property when loading a .msg file from disk that contains an Active Directory address (I have seen via other means that the .msg's display name is the user's full name, and the email address is what looks like a Active Directory query)?

Applies to: Rebex Secure Mail
commented Feb 28, 2011 by Lukas Matyska (55,430 points)
.msg saved from Outlook can contain addresses like /O=REBEXCR/OU=FIRST ADMINISTRATIVE GROUP/CN=RECIPIENTS/CN=JAN.SOTOLA Is this what you want to retrieve?
commented Feb 28, 2011 by Josh Zacharias (150 points)
Yes. That is what is stored in my .msg files. I need the associated email addresses (or even just that string and I can do the lookup myself) for printing reasons.

2 Answers

0 votes
answered Mar 1, 2011 by Lukas Matyska (55,430 points)
edited Dec 14, 2012
 
Best answer

We added new option LoadMsgProperties to enable retrieving of various MSG properties. This code can be used to retrieve all supported MSG properties:

// load MSG into mail message
MailMessage mail = new MailMessage();
mail.Options = Rebex.Mime.MimeOptions.LoadMsgProperties;
mail.Load("mail.msg");

// get required properties
// AdressType is typically from set {EX, SMTP}
// RecipientType is typically from set {To, Cc, Bcc}
string fromName = GetHeader(mail, "X-Outlook-SentRepresentingName");
string fromAdress = GetHeader(mail, "X-Outlook-SentRepresentingEmailAddress");
string fromAdressType = GetHeader(mail, "X-Outlook-SentRepresentingAddressType");

string senderName = GetHeader(mail, "X-Outlook-SenderName");
string senderAdress = GetHeader(mail, "X-Outlook-SenderEmailAddress");
string senderAdressType = GetHeader(mail, "X-Outlook-SenderAddressType");

for (int i = 0; i < int.MaxValue; i++)
{
    string recipientType = GetHeader(mail, string.Format("X-Outlook-Recipient{0}-Type", i));
    string recipientName = GetHeader(mail, string.Format("X-Outlook-Recipient{0}-Name", i));
    string recipientSmtpAdress = GetHeader(mail, string.Format("X-Outlook-Recipient{0}-SmtpAddress", i));
    string recipientAdress = GetHeader(mail, string.Format("X-Outlook-Recipient{0}-EmailAddress", i));
    string recipientAdressType = GetHeader(mail, string.Format("X-Outlook-Recipient{0}-AddressType", i));

if (recipientType == null)
        break;
}

private static string GetHeader(MailMessage mail, string headerName)
{
    MimeHeader h = mail.Headers[headerName];
    if (h == null || h.Value == null)
        return null;
    else
        return h.Value.ToString();
}

Current trial build with this functionality can be downloaded here.

0 votes
answered Dec 14, 2012 by Lukas Matyska (55,430 points)
edited Dec 14, 2012

Just for curiosity. Following code seems to be working for conversion EX to SMTP address:

using System.DirectoryServices;

public static string ExToSmtp(string ex)
{
    if (ex == null)
        return null;

    // return if looks like SMTP
    if (ex.IndexOf('@') > 0)
        return ex;

    // return if there is no exchange CN
    int idx = ex.LastIndexOf("/cn=", StringComparison.OrdinalIgnoreCase);
    if (idx < 0)
        return null;

    // get exchange CN
    string cn = ex.Substring(idx + 4);
    if (cn.Length == 0)
        return null;

    // search for the exchange CN
    DirectorySearcher searcher = new DirectorySearcher(string.Format("(legacyExchangeDN=*{0}*)", cn));
    foreach (SearchResult result in searcher.FindAll())
    {
        foreach (string dn in result.Properties["legacyExchangeDN"])
        {
            // check whether this is requested CN
            if (!dn.EndsWith("/cn=" + cn, StringComparison.OrdinalIgnoreCase))
                continue;

            // find the default SMTP address
            foreach (string item in result.Properties["proxyAddresses"])
            {
                if (item.StartsWith("SMTP:", StringComparison.Ordinal))
                    return item.Substring(5);
            }
        }
    }
    return null;
}

Uses additional reference: System.DirectoryServices.dll

...