Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I read the Received Date from Outlook MSG files -without- the Outlook API?

I need to read stuff from an Outlook msg file. Currently I'm using a class from CodeProject.com project to accomplish this, since deploying VSTO and Outlook on a server is not an option.

This class gets To, From, CC, Subject, Body, and everything else I need from the msg file, except Date information (such as Received Date and Sent Date).

There is some (really, really low-level) documentation on how to get stuff out of msg files on MSDN, but it's a little beyond the scope of this project and doesn't mention dates at all.

Ideally I'd be able to have a drop-in replacement for the class I am using now (OutlookStorage.cs in the previously mentioned CodeProject) or be able to modify the existing class a bit. To modify, I would need the correct 4 character hexidecimal prop identifier for received date. For instance, Subject is listed as PR_SUBJECT = "0037" and Body is listed as PR_BOY = "1000".

like image 306
スーパーファミコン Avatar asked Aug 12 '09 14:08

スーパーファミコン


People also ask

How do I show the date received in Outlook?

Click on the View tab. Then click View Settings. From the Format drop-down menu (click the down arrow to the right of the format field), then select how you want it displayed. In the below example the format selected would display date and time.

How do I read an Outlook message file?

Open the MSG with Outlook (in Windows): If you have access to Outlook, double-click the MSG and it'll automatically open using Outlook. If it doesn't, right-click on it, choose the 'Open With' option, and select 'Outlook'. Alternatively, you can copy/paste the MSG manually.

How do I show emails by date?

To locate emails received before a certain date, type into the search bar Before:YYYY/MM/DD and press Enter. So, for example, if you want to search for emails received before January 17th, 2015, then type: To locate emails received after a certain date, type into the search bar After:YYYY/MM/DD and press Enter.


4 Answers

If you're using OutlookStorage.cs from CodeProject, then add the following:

private const string PR_RECEIVED_DATE="007D";
private const string PR_RECEIVED_DATE_2 = "0047";

...

/// <summary>
/// Gets the date the message was received.
/// </summary>
public DateTime ReceivedDate
{
    get
    {
        if (_dateRevieved == DateTime.MinValue)
        {
            string dateMess = this.GetMapiPropertyString(OutlookStorage.PR_RECEIVED_DATE);
            if (String.IsNullOrEmpty(dateMess))
            {
                dateMess = this.GetMapiPropertyString(OutlookStorage.PR_RECEIVED_DATE_2);
            }
            _dateRevieved = ExtractDate(dateMess);
        }
        return _dateRevieved;
        //return ExtractDate(dateMess);
    }
}

private DateTime _dateRevieved = DateTime.MinValue;

private DateTime ExtractDate(string dateMess)
{
    string matchStr = "Date:";

    string[] lines = dateMess.Split(new String[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
    foreach (string line in lines)
    {
        if (line.StartsWith(matchStr))
        {
            string dateStr = line.Substring(matchStr.Length);
            DateTime response;
            if (DateTime.TryParse(dateStr, out response))
            {
                return response;
            }
        }
    }
    return DateTime.MinValue;                
}
like image 107
ZipXap Avatar answered Oct 01 '22 05:10

ZipXap


I think the Aspose library will do what you want, ok it a 3rd party lib so may not be what you want. There are a few vbs scripts around that get basic infomation out of msg files that could be translated.

like image 40
76mel Avatar answered Oct 03 '22 05:10

76mel


Got a hint from this:

string fullFileName = "c:\message.msg";
DateTime dateRevieved = new DateTime();

StreamReader sr = new StreamReader(fullFileName, Encoding.Default);
string full = sr.ReadToEnd();

string date;
int iStart;
int iLast;

string caption;

//This -should- handle all manner of screwage
//The ONLY way it would not is if someone guessed the -exact- to-the-second
//time that they send the message, put it in their subject in the right format
while (true) {      //not an infinite loop, I swear!

    caption = "Date:";
    if (full.IndexOf("Date:") > -1) {   //full shortens with each date is removed
        string temp = "";

        iStart = full.LastIndexOf(caption);
        temp = full.Remove(0, iStart + caption.Length);
        full = full.Substring(0, iStart);

        iLast = temp.IndexOf("\r\n");
        if (iLast < 0) {
            date = temp;
        } else {
            date = temp.Substring(0, iLast);
        }

        date = date.Trim();

        if (date.Contains(subject) || subject.Contains(date)) {
            continue;   //would only happen if someone is trying to screw me
        }

        try {
            dateRevieved = DateTime.Parse(date); //will fail if not a date
            break;   //if not a date breaks out of while loop
        } catch {
            continue;   //try with a smaller subset of the msg
        }
    } else {
        break;
    }
}

This is kind of a hack compared to the ways you can get other things from msg files using something this lovely project. Still, it's stood up to everything I have thrown against it, and as noted the -only- way to fool it is to put the exact to-the-second date in the subject line in the proper format.

like image 26
スーパーファミコン Avatar answered Oct 01 '22 05:10

スーパーファミコン


to combine your two posts I would suggest the following solution:

To modify, I would need the correct 4 character hexidecimal prop identifier for recieved date. For instance, Subject is listed as PR_SUBJECT = "0037" and Body is listed as PR_BOY = "1000".

Look for "007D".

Use the method you posted in your second post on the received data to eliminate the problem when the same (date) string is inside the subject.


I have to mention that this method doesn't seem to work on internal eMails: In mails I receive from colleagues, there is no substg1.0_007Dxxxx-Property.

Here, the date seems to be hidden in substg1.0_0047xxxx.

All the best!

inno

like image 37
Inno Avatar answered Oct 02 '22 05:10

Inno