2017-05-10 63 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()的引用,但唯一一次我认为有必要的是引用停留时间过长,这可能是在递归文件遍历期间或其他情况。这不是确切的案例。 –

相关问题