Исключение при перечислении элементов Outlook в C # - PullRequest
1 голос
/ 27 января 2010

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

Но независимо от того, как я к этому подхожу, я достигаю установленного для Exchange 255 RPC-подключений.

Я абсолютно застрял в том, что является причиной ошибки - насколько я вижу, я все связал в одном методе и вызываю Marshal.ReleaseComObject .... Я даже принимаю снижение производительности открытия и закрытия самого дескриптора приложения Outlook.

Любой совет был бы в высшей степени признателен ... (Кажется, я не могу понять, почему мой код выглядит неправильно в предварительном просмотре, поэтому в целях безопасности я тоже поместил его на pastebin ... http://pastebin.com/m637eb95)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Interop;
using System.Runtime.InteropServices;

namespace HandleMailingResponses
{
    class OutlookFolderTableScraper
    {
        public List<OutlookItem> GetItemsFromFolder(string folderName)
        {
            List<OutlookItem> returnList = new List<OutlookItem>();

            Application outlookHandle = new Application();
            NameSpace outlookNamespace = outlookHandle.GetNamespace("MAPI");
            Folders rootOutlookFolders = outlookNamespace.Folders;

            outlookNamespace.Logon(null, null, null, true);

            Folder requestedRoot = enumerateFolders(rootOutlookFolders, folderName);
            Folders theseFolders = requestedRoot.Folders;
            Folder thisInbox = enumerateFolders(theseFolders, "Inbox");

            Marshal.ReleaseComObject(requestedRoot);
            requestedRoot = null;
            Marshal.ReleaseComObject(rootOutlookFolders);
            rootOutlookFolders = null;

            string storeID = thisInbox.StoreID;

            Table thisTable = thisInbox.GetTable("",OlTableContents.olUserItems);

            //By default each item has the columns EntryID, Subject, CreationTime, LastModificationTime and MessageClass
            //we can add any of the other properties the MailItem or ReportItem object would have....
            Columns theseColumns = thisTable.Columns;
            theseColumns.Add("SenderEmailAddress");

            Marshal.ReleaseComObject(thisInbox);
            thisInbox = null;

            outlookNamespace.Logoff();
            Marshal.ReleaseComObject(outlookNamespace);
            outlookNamespace = null;
            outlookHandle.Quit();
            Marshal.ReleaseComObject(outlookHandle);
            outlookHandle = null;

            int count = 0;
            while (!thisTable.EndOfTable)
            {
                Row thisRow = thisTable.GetNextRow();
                object[] theseValues = (object[]) thisRow.GetValues();
                Console.WriteLine("processed {0}",count++);

                //get the body from this item
                string messageClass = (string)theseValues[4];
                string entryID = (string)theseValues[0];
                string body = getItemBody(entryID,storeID, messageClass);

                returnList.Add(new OutlookItem((string)theseValues[5], (string)theseValues[1], body, messageClass, entryID));
            }



            return returnList;
        }

        private string getItemBody(string entryID, string storeID, string messageClass)
        {
            Application outlookHandle = new Application();
            NameSpace outlookNamespace = outlookHandle.GetNamespace("MAPI");
            outlookNamespace.Logon(null, null, null, true);
            string body;

            if (messageClass.ToLower().StartsWith("report"))
            {
                ReportItem thisItem = (ReportItem)outlookNamespace.GetItemFromID(entryID, storeID);
                body = thisItem.Body;
                thisItem.Close(OlInspectorClose.olDiscard);
                //release this com reference
                int releaseResult;
                do
                {
                    releaseResult = Marshal.ReleaseComObject(thisItem);
                } while (releaseResult != 0);
            }
            else
            {
                MailItem thisItem = (MailItem)outlookNamespace.GetItemFromID(entryID, storeID);
                body = thisItem.Body;
                thisItem.Close(OlInspectorClose.olDiscard);
                //release this com reference
                int releaseResult;
                do
                {
                    releaseResult = Marshal.ReleaseComObject(thisItem);
                } while (releaseResult != 0);
            }

            outlookNamespace.Logoff();
            outlookNamespace = null;
            outlookHandle.Quit();
            outlookHandle = null;


            GC.Collect();
            GC.WaitForPendingFinalizers();

            return body;
        }

                    /// <summary>
        /// Iterates through an Outlook.Folders object searching for a folder with the given name
        /// </summary>
        /// <param name="rootFolder">An Outlook.Folder object</param>
        /// <param name="targetFolder"></param>
        /// <returns></returns>
        private Folder enumerateFolders(Folders rootFolders, string targetFolder)
        {
            Folder returnFolder = null;
            System.Collections.IEnumerator thisEnumerator = rootFolders.GetEnumerator();
            while (thisEnumerator.MoveNext())
            {
                Folder f = (Folder)thisEnumerator.Current;
                string name = f.Name;
                if (targetFolder.ToLower().Equals(name.ToLower()))
                {
                    returnFolder = f;
                    break;
                }
            }
            ICustomAdapter adapter = (ICustomAdapter)thisEnumerator;
            Marshal.ReleaseComObject(adapter.GetUnderlyingObject());
            adapter = null;
            return returnFolder;
        }
        }

}

Ответы [ 2 ]

1 голос
/ 27 января 2010

У меня были почти такие же требования, как и у вас.следующий пример приложения действительно хороший справочник:

http://www.c -sharpcorner.com / UploadFile / rambab / OutlookIntegration10282006032802AM / OutlookIntegration.aspx

относительно "Exchange принудительно установлен 255 RPCлимит соединений "проверьте эти ссылки:
http://www.dimastr.com/Redemption/faq.htm
http://www.outlookcode.com/threads.aspx?forumid=2&messageid=26321

0 голосов
/ 27 января 2010

Не создавайте новый объект Application каждый раз, когда вы вызываете функцию, сохраняйте его как закрытую переменную члена вашего класса, пока он вам больше не понадобится. Таким образом, вам нужно всего лишь вызвать Namespace.Logon в вашем конструкторе.

...