我有以下情况: Iam编程Outlook 2010 AddIn并想要一个全局事件,当任何项目添加到任何文件夹时通知我。 outlook的对象模型不提供全局ItemAdd事件,它仅提供文件夹的Items Collection的ItemAdd事件。 因此,为了解决这个问题,我将所有ItemAddEvents捆绑到了FolderManager类的GlobalItemAddedEvent。
以下问题: 一切都在我的机器上工作正常但是当客户执行它时,初始化大约需要2分钟(许多不同的邮箱和文件夹),但没关系,它可能正确初始化。完成加载并显示Outlook后,Outlook挂起并且不接受任何命令,并且必须被任务管理器杀死
我真的在这方面苦苦挣扎,无法找到任何解决方案或解释。有没有人知道在这里发生什么以及如何解决它?谢谢!示例代码:
public class FolderManager : IFolderManager
{
public event GlobalItemAdd GlobalItemAdded;
private Dictionary<string, FolderContainer> _foldersMap = new Dictionary<string, FolderContainer>();
private void InitFolders()
{
HashSet<string> excludeFolderIds = new HashSet<string>();
Outlook.Stores stores = application.Session.Stores;
foreach(Outlook.Store store in stores){
//exclude outbox folder from event
try
{
Outlook.MAPIFolder exclude = store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderOutbox);
excludeFolderIds.Add(exclude.EntryID);
}
catch(COMException ex){
}
}
//attach events to folders
List<Outlook.Folder> allFolders = application.Session.GetAllFolders();
foreach (Outlook.Folder folder in allFolders)
{
if(excludeFolderIds.Contains(folder.EntryID)){
continue;
}
FolderContainer folderContainer = new FolderContainer(folder, this);
_foldersMap[folderContainer.EntryID] = folderContainer;
}
}
public void ItemAdded(object added, Outlook.MAPIFolder parent)
{
OnGlobalItemAdded(added,parent);
}
}
public class FolderContainer{
//Instance variables & Properties
//...
//...
public FolderContainer(Outlook.MAPIFolder folder,IFolderManager manager)
{
_manager = manager;
_thisFolder = folder;
_OlItems = folder.Items;
_OlFolders = folder.Folders;
if (_OlItems != null)
{
_OlItems.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(ItemAdd);
}
if (_OlFolders != null)
{
_OlFolders.FolderAdd += new Outlook.FoldersEvents_FolderAddEventHandler(FolderAdd);
}
}
private void ItemAdd(object item)
{
_manager.ItemAdded(item,_thisFolder);
}
}
答案 0 :(得分:2)
我建议订阅扩展MAPI通知(低级别事件)而不是使用Outlook对象模型。使用Outlook保持一堆COM对象不是一个好主意。我总是建议立即释放底层的COM对象。完成使用后,使用System.Runtime.InteropServices.Marshal.ReleaseComObject释放Outlook对象。如果您的加载项尝试枚举存储在Microsoft Exchange Server上的集合中超过256个Outlook项目,这一点尤为重要。如果您未及时发布这些对象,则可以达到Exchange对任何时候打开的最大项目数的限制。然后在Visual Basic中将变量设置为Nothing(C#中为null)以释放对该对象的引用。请在Systematically Releasing Objects文章中详细了解相关内容。
例如,作为一种解决方法,您可以考虑使用扩展MAPI周围的任何包装(例如Redemption)。
答案 1 :(得分:1)
Items.ItemAdd / etc公开的MAPI事件。仅用于UI目的。您不应该将它们用于任何类型的同步。事件不能保证解雇。
话虽如此,在MAPI级别上,商店(IMsgStore)将在创建消息时触发fnevObjectCreated事件。您只能在扩展MAPI(C ++或Delphi)中使用该事件。如果使用Redemption是一个选项,则会公开RDOSession.OnMessageCreated事件。