Парсинг писем в outloook с C # - PullRequest
4 голосов
/ 12 марта 2012

Я пишу программу для чтения всех моих электронных писем, в конечном итоге поиск будет более конкретным, но сейчас я хочу прочитать все электронные письма в моем почтовом ящике. у меня работает код, который читает то, что я хочу до 169 по некоторым причинам ...

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();
        }


    }
}

Цикл читает до 169 электронных писем, а затем вылетает, также он начинает читать электронные письма в произвольную дату ... Я не уверен, что мешает ему читать все электронные письма ...

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

Нажмите любую клавишу для продолжения. , .

Ответы [ 2 ]

4 голосов
/ 13 марта 2012

Я предполагаю, что в вашей папке входящих есть элементы, которые не применяют интерфейс Microsoft.Office.Interop.Outlook.MailItem, и, следовательно, код падает при прохождении цикла и попытке приведения.Один из возможных обходных путей, если вы используете .NET4, поскольку он поддерживает динамический режим, - это не приведение объекта, а передача его в динамическую переменную.

dynamic item = inboxFolder.Items[counter];

Это сработало дляУ меня возникли проблемы с обработкой приглашений на собрания в папке входящих сообщений.

Полный измененный код:

 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();
        }
    }

}

1 голос
/ 12 марта 2012

Если вы хотите только MailItems, вам следует проверить, что получаемый вами предмет является действительным MailItem, а не предполагать, что он у вас есть.Это может быть CalendarItem, DocumentItem и т. Д., Который варьируется на olItemType.Ваш текущий код явно предполагает, что у вас есть только MailItems во входящих.

item = inboxFolder.Items[counter] as Microsoft.Office.Interop.Outlook.MailItem;
if (item != null)
{
   ....
}

Ваша ошибка указывает, что у вас может быть MailItem - но это может быть отчет о доставке почты ( Чтение квитанциии т. д. ).См. этот пост для справки с ошибкой приведения.Они предлагают использовать интерфейс таблицы Outlook в качестве обходного пути и проверять объект Class.Это может быть другой вариант для вас.

...