使用RDO / MAPI提取大型公用文件夹存储并获取E_MAPI_TOO_BIG

时间:2017-05-10 15:52:21

标签: c# com interop mapi outlook-redemption

我正在尝试使用RDO 5.14从Exchange Server 2010导出公司相当大的公用文件夹布局(000s文件夹)的内容。

我遇到了很多人发现的问题,因为在某些时候,Exchange 2010会出现错误E_MAPI_TOO_BIG,因为我使用的用户违反了交换存储限制documented here

在许多情况下,已接受的解决方案是每隔一段时间拨打while (Marshal.ReleaseComObject(ref)>0)GC.Collect()偶尔拨打for (int i = 1; i < items.Count; ++i) { IRDOMail item = items.Item(i); string SUCCESS = item.EntryID; } ,这似乎可以处理更多项目,但仍然无法让我获得更多超过500条消息。

有些玩弄代码。它揭示了以下令人惊讶的事实(至少对我而言)。

如果我迭代这样的文件夹中的项目没有问题:

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

但是,如果我在某些时候使用此代码示例,则在E_MAPI_TOO_BIG中失败(代码中的其他地方试图访问其他文件夹):

order

此时我已经达到了我的COM技能的极限。它告诉我,在.NET InterOp中取消引用MailItem的COM属性的某些部分最终会抓取我无法释放的引用。如果是这种情况,我不知道如何解决它,如果有的话?

如果我使用没有RDO的MAPI,可以看到类似(但不同)的行为,进一步表明它是MAPI(14.0)的怪癖?

2 个答案:

答案 0 :(得分:1)

这结果是程序结构的问题,而不是RDO或MAPI的直接问题。具体而言,问题是尝试递归处理整个树项。

似乎从文件夹访问MAPI / RDO MailItem的任何属性就会从文件夹创建一个内部引用回到该项目。虽然我不确定这是否属实,也不确定如何验证。

因此,如果结构的一个子分支(不仅仅是一个文件夹)包含超过500条消息,您将获得E_MAPI_TOO_BIG尝试以所述方式“访问”结构。

然后解决方案是使用递归来构建文件夹EntryId的列表,然后使用GetFolderFromId()遍历该列表以获取文件夹,然后迭代这些项目。到目前为止,我发现的MAPI / RDO编程资源都没有提及这一事实。

<强>更新

在花费更多时间尝试使MAPI在托管代码中工作之后,我得出的结论是,尝试做我正在尝试的事情是一个根本不好的主意。虽然上面的解决方案让我更进一步,但当我尝试访问消息的更多属性时,它最终再次失败(同样的错误)。

事后看来,问题似乎是它几乎可以运作,并且很多人已经设法通过它,因此有相当多的资源在线证明这一点。但是,由于Microsoft不支持在托管代码中执行MAPI,因此我们似乎开始处于摇摇欲坠的状态。即使这是COM Interop而不是直接MAPI。

在Exchange中大规模进行任何操作都需要使用其他Exchange技术。我最终使用了EWS,它似乎完整,更重要的是,可靠。我希望这有助于某人!

答案 1 :(得分:0)

您需要使用ReleaseComObject:

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