C# 使用RDO/MAPI提取大型公用文件夹存储并使E_MAPI_过大

C# 使用RDO/MAPI提取大型公用文件夹存储并使E_MAPI_过大,c#,com,interop,mapi,outlook-redemption,C#,Com,Interop,Mapi,Outlook Redemption,我正在尝试使用RDO 5.14从Exchange Server 2010导出公司相当大的公用文件夹布局(000个文件夹)的内容 我遇到了很多人都会发现的问题,在某个时候,Exchange 2010给出的错误E_MAPI_太大,因为我使用的用户已经违反了Exchange存储限制 在许多情况下,公认的解决方案是每隔一段时间调用while(Marshal.ReleaseComObject(ref)>0),以及GC.Collect(),这似乎允许处理更多的项,但仍然不允许我在中获取超过500条消息 有些

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

我遇到了很多人都会发现的问题,在某个时候,Exchange 2010给出的错误E_MAPI_太大,因为我使用的用户已经违反了Exchange存储限制

在许多情况下,公认的解决方案是每隔一段时间调用
while(Marshal.ReleaseComObject(ref)>0)
,以及
GC.Collect()
,这似乎允许处理更多的项,但仍然不允许我在中获取超过500条消息

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

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

for (int i = 1; i < items.Count; ++i) {
    IRDOMail item = items.Item(i);
    string SUCCESS = item.EntryID;
}
for(int i=1;i
但是,如果我在某个时候使用此代码示例,它会失败(代码中的其他地方尝试访问其他文件夹),E_MAPI_太大:

for (int i = 1; i < items.Count; ++i) {
    IRDOMail item = items.Item(i);
    string FAIL = item.Subject;
}
for(int i=1;i
在这一点上,我已经达到了我的COM技能的极限。它向我建议,在.NET InterOp中取消引用MailItem的COM属性的某些部分最终会获取一个我无法发布的引用。如果是这样的话,我不知道如何修复它,如果有的话


如果我在不使用RDO的情况下使用MAPI,可以看到类似(但不同)的行为,这进一步表明这是MAPI(14.0)的一个怪癖。

您需要使用ReleaseComObject:

for (int i = 1; i < items.Count; ++i) {
    IRDOMail item = items.Item(i);
    string FAIL = item.Subject;
    Marshal.ReleaseComObject(item); 
}
for(int i=1;i
这是程序结构的问题,而不是RDO或MAPI的直接问题。具体来说,问题是试图递归地处理整个树

似乎从文件夹访问MAPI/RDO邮件项的任何属性都会创建一个从文件夹返回该项的内部引用。虽然我不确定这是真的,也不知道如何验证它

因此,如果该结构的一个子分支(而不仅仅是一个文件夹)包含的邮件超过500封,那么,如果您试图以所述方式“访问”该结构,则会得到E_MAPI_太大

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

更新

在花了更多的时间尝试让MAPI在托管代码中工作之后,我得出了这样的结论:尝试并执行我尝试的操作从根本上说是个坏主意。虽然上面的解决方案让我走得更远,但当我试图访问消息的更多属性时,它最终再次失败(出现相同的错误)

事后看来,问题似乎是,它几乎奏效了,很多人都成功地在这方面度过了难关,因此有相当多的资源在线演示了这一点。但由于Microsoft不支持在托管代码中执行MAPI,因此我们的起点似乎并不稳固。即使这是COM互操作而不是直接MAPI


在我看来,用Exchange做任何大规模的事情都需要使用其他Exchange技术之一。我最终使用了EWS,它看起来是完整的,更重要的是,它是可靠的。我希望这对别人有帮助

这似乎没有什么区别。假设超出范围的“项”足以释放引用?我在网上找到了各种推荐添加Marshal.ReleaseComObject()的引用,但我认为唯一有必要添加的是引用在作用域中停留的时间过长,这可能是在递归文件夹遍历或类似的过程中。这里的情况并非如此。您只需要非常小心挂起引用,尤其是避免使用多点表示法。