2017-05-10 24 views
1

我試圖使用RDO 5.14從Exchange Server 2010中導出我公司相當大的公用文件夾佈局(文件夾數量爲000)的內容。使用RDO/MAPI提取大型公用文件夾存儲並獲取E_MAPI_TOO_BIG

我遇到了很多人發現的問題,因爲在某些時候,Exchange 2010提供了錯誤E_MAPI_TOO_BIG,因爲我正在使用的用戶已經違反了Exchange商店的限制documented here

在許多情況下接受的解決方案是在不出現,讓更多的項目的處理,但仍然不允許我在獲得超過500個消息的同時調用while (Marshal.ReleaseComObject(ref)>0)每個裁判和GC.Collect()一次。

有些玩弄代碼。它揭示了以下令人驚訝的事情(至少對我而言)的事實。

如果我遍歷這樣的文件夾中的項目是沒有問題的:

for (int i = 1; i < items.Count; ++i) { 
    IRDOMail item = items.Item(i); 
    string SUCCESS = item.EntryID; 
} 

但是,如果我在某些時候使用此代碼示例,它失敗(在其他地方的代碼試圖訪問其他文件夾)與E_MAPI_TOO_BIG:

for (int i = 1; i < items.Count; ++i) { 
    IRDOMail item = items.Item(i); 
    string FAIL = item.Subject; 
} 

在這一點上,我已經達到了我的COM技能的極限。它向我建議,在.NET InterOp中取消引用MailItem的COM屬性的某些部分最終會抓取我無法發佈的引用。如果是這種情況,我不知道我該如何修復它,如果有的話?

如果我在沒有RDO的情況下使用MAPI,可以看到類似(但不同)的行爲,進一步表明它是MAPI(14.0)的怪癖?

回答

1

這竟然是與程序結構的問題,而不是直接與問題無論RDO或MAPI。特別是該問題試圖遞歸處理整個樹項目。

看起來好像從該文件夾訪問MAPI/RDO MailItem的任何屬性都會創建一個從該文件夾返回到該項目的內部引用。雖然我不確定這是否屬實,也不知道如何驗證。

因此,如果結構中的一個子分支(不只是一個文件夾)包含超過500條消息,您將獲得E_MAPI_TOO_BIG嘗試以所述方式「訪問」結構。

然後,解決方案是使用遞歸來構建文件夾EntryId的列表,然後遍歷該列表使用GetFolderFromId()獲取該文件夾,然後迭代項目。迄今爲止,我發現的MAPI/RDO編程資源都沒有提到這個事實。

UPDATE

花費更多的時間試圖讓MAPI在託管代碼的工作之後,我已經到了,這是一個根本的一個壞主意,試圖做什麼,我正嘗試的結論。雖然上面的解決方案讓我有點進一步,但當我試圖訪問消息的更多屬性時,它最終再次失敗(具有相同的錯誤)。

事後看來,這個問題似乎是非常近乎成功的,很多人都設法解決這個問題,因此有相當多的資源在線展示了這一點。但是,由於在託管代碼中執行MAPI不受Microsoft支持,所以我們似乎開始時不穩固。即使這是COM Interop,而不是直接的MAPI。

對Exchange的規模做任何事情都需要使用其他Exchange技術之一。我最終使用了EWS,這看起來很完整,更重要的是,可靠。我希望這可以幫助別人!

+0

你只需要非常小心地懸掛引用,特別是避免使用多點表示法。 –

0

您需要使用ReleaseComObject的:

for (int i = 1; i < items.Count; ++i) { 
    IRDOMail item = items.Item(i); 
    string FAIL = item.Subject; 
    Marshal.ReleaseComObject(item); 
} 
+0

這似乎沒有任何區別。據推測,「範圍」超出範圍足以釋放參考?我在網上發現了各種推薦添加Marshal.ReleaseComObject()的引用,但唯一一次我認爲有必要的是引用停留時間過長,這可能是在遞歸文件遍歷期間或其他情況。這不是確切的案例。 –

相關問題