Parsing emails in outloook with C#

stihl picture stihl · Mar 12, 2012 · Viewed 17.5k times · Source

I'm writing a program to read all my outlook emails, eventually the search will be more specific but for now i want to read all the email in my inbox. i have code running that reads what i want up to 169 for some reason...

namespace reademail
{
static class Program
{
    public static Microsoft.Office.Interop.Outlook.Application myApp;

    public static void Main(string[] args)
    {            
       // myApp = new Microsoft.Office.Interop.Outlook.Application();
        //myApp.NewMailEx += new Microsoft.Office.Interop.Outlook.ApplicationEvents_11_NewMailExEventHandler(OutlookNewMailReceived);
        ReadMail();
    }

    static void ReadMail()
    {
        Microsoft.Office.Interop.Outlook.Application app = null;
        Microsoft.Office.Interop.Outlook._NameSpace ns = null;
        Microsoft.Office.Interop.Outlook.MailItem item = null;
        Microsoft.Office.Interop.Outlook.MAPIFolder inboxFolder = null;


            app = new Microsoft.Office.Interop.Outlook.Application();
            ns = app.GetNamespace("MAPI");
            //ns.Logon(null, null, false, false);

            inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
           // subFolder = inboxFolder.Folders["Inbox"]; //folder.Folders[1]; also works
            Console.WriteLine("Folder Name: {0}, EntryId: {1}", inboxFolder.Name, inboxFolder.EntryID);
            Console.WriteLine("Num Items: {0}", inboxFolder.Items.Count.ToString());

            //System.IO.StreamWriter strm = new System.IO.StreamWriter("C:/Test/Inbox.txt");
            for (int counter = 1; counter <= inboxFolder.Items.Count; counter++)
            {
                Console.Write(inboxFolder.Items.Count + " " + counter);
                item = (Microsoft.Office.Interop.Outlook.MailItem)inboxFolder.Items[counter];
                Console.WriteLine("Item: {0}", counter.ToString());
                Console.WriteLine("Subject: {0}", item.Subject);
                Console.WriteLine("Sent: {0} {1}", item.SentOn.ToLongDateString(), item.SentOn.ToLongTimeString());
                Console.WriteLine("Sendername: {0}", item.SenderName);
                Console.WriteLine("Body: {0}", item.Body);
                //strm.WriteLine(counter.ToString() + "," + item.Subject + "," + item.SentOn.ToShortDateString() + "," + item.SenderName);

            }
            //strm.Close();
        }


    }
}

The loop reads up to 169 emails and then crashes, also it starts reading emails at what seems to be an arbitrary date...I'm not sure whats preventing it from reading all emails...

Folder Name: Inbox, EntryId: 000000003527EA8DB4FFC04EB6ABA4DE31CB4BA40100C6D3EBA
DBDB57E438D0B53C5FB515CC50000660627C70000
Num Items: 1048
System.InvalidCastException: Unable to cast COM object of type 'System.__ComObje
ct' to interface type 'Microsoft.Office.Interop.Outlook.MailItem'. This operatio
n failed because the QueryInterface call on the COM component for the interface
with IID '{00063034-0000-0000-C000-000000000046}' failed due to the following er
ror: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERF
ACE)).
 at CallSite.Target(Closure , CallSite , Object )
 at reademail.Program.ReadMail() in C:\Documents and Settings\DBubel\my docume
nts\visual studio 2010\Projects\reademail\reademail\Program.cs:line 60

Press any key to continue . . .

Answer

Roberto Hernandez picture Roberto Hernandez · Mar 12, 2012

My guess is that you have items in your inbox that do not apply the Microsoft.Office.Interop.Outlook.MailItem interface and therefore the code crashes while going through the loop and attempting to cast. One possible workaround, if you are using .NET4 since it has support for dynamic, is not to cast the object but rather pass it to a dynamic variable.

dynamic item = inboxFolder.Items[counter];

This worked for me as your code was having problems handling meeting invites in the inbox folder.

Full modified code:

 namespace reademail
    {
     static class Program
    {
        public static Microsoft.Office.Interop.Outlook.Application myApp;

        public static void Main(string[] args)
        {
            // myApp = new Microsoft.Office.Interop.Outlook.Application();
            //myApp.NewMailEx += new Microsoft.Office.Interop.Outlook.ApplicationEvents_11_NewMailExEventHandler(OutlookNewMailReceived);
            ReadMail();
        }

        static void ReadMail()
        {
            Microsoft.Office.Interop.Outlook.Application app = null;
            Microsoft.Office.Interop.Outlook._NameSpace ns = null;
            //Microsoft.Office.Interop.Outlook.MailItem item = null;
            Microsoft.Office.Interop.Outlook.MAPIFolder inboxFolder = null;


            app = new Microsoft.Office.Interop.Outlook.Application();
            ns = app.GetNamespace("MAPI");
            //ns.Logon(null, null, false, false);

            inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
            // subFolder = inboxFolder.Folders["Inbox"]; //folder.Folders[1]; also works
            Console.WriteLine("Folder Name: {0}, EntryId: {1}", inboxFolder.Name, inboxFolder.EntryID);
            Console.WriteLine("Num Items: {0}", inboxFolder.Items.Count.ToString());

            //System.IO.StreamWriter strm = new System.IO.StreamWriter("C:/Test/Inbox.txt");
            for (int counter = 1; counter <= inboxFolder.Items.Count; counter++)
            {
                Console.Write(inboxFolder.Items.Count + " " + counter);
                dynamic item = inboxFolder.Items[counter];
                //item = (Microsoft.Office.Interop.Outlook.MailItem)inboxFolder.Items[counter];
                Console.WriteLine("Item: {0}", counter.ToString());
                Console.WriteLine("Subject: {0}", item.Subject);
                Console.WriteLine("Sent: {0} {1}", item.SentOn.ToLongDateString(), item.SentOn.ToLongTimeString());
                Console.WriteLine("Sendername: {0}", item.SenderName);
                Console.WriteLine("Body: {0}", item.Body);
                //strm.WriteLine(counter.ToString() + "," + item.Subject + "," + item.SentOn.ToShortDateString() + "," + item.SenderName);

            }
            //strm.Close();
        }
    }

}