我正在为Outlook 2007创建一个插件,在收到邮件时读取它,然后重写它.插件工作得很好,并为没有将其移动到另一个文件夹的Outlook规则的项重写邮件.如果有规则,大约50%的时间仍然可以.另外50%的时间,规则会在我的插件完成之前移动邮件项目.我收到以下错误:
"由于对象已被删除,因此无法执行操作."
我正在使用NewMailEx事件来调用我的重写函数:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.NewMailEx += new Outlook.ApplicationEvents_11_NewMailExEventHandler(olApp_NewMail);
}
Run Code Online (Sandbox Code Playgroud)
在Outlook 2007中,NewMailEx为邮件提供了entryID.此entryID最初用于确定要使用的邮件对象:
Outlook.NameSpace outlookNS = this.Application.GetNamespace("MAPI");
Outlook.MAPIFolder mFolder = this.Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.MailItem mail;
try
{
mail = (Outlook.MailItem)outlookNS.GetItemFromID(entryIDCollection, Type.Missing);
}
catch (Exception e) { Debug.WriteLine("exception with non-mail item " + entryIDCollection + ": " + e.ToString()); return; }
Run Code Online (Sandbox Code Playgroud)
我认为我可以使用这个entryID(上面的代码可以工作),并遍历我的所有文件夹(在交换机上和我的计算机上),寻找相同的邮件ID.当我最终迭代到邮件所在的位置时,移动邮件的EntryID与entryIDCollection非常不同.
也许我会以错误的方式解决这个问题.有谁知道如何阻止事件传播直到我完成,或者如何追踪移动的电子邮件?
这是我的代码遍历文件夹,万一有人好奇:
try
{
mail.Subject = new_subj;
mail.Body = "";
mail.HTMLBody = text;
mail.ClearConversationIndex();
mail.Save();
}
catch (Exception ex)
{
//It wasn't caught in time, so we need to find the mail:
ArrayList unreadFolders = new ArrayList();
foreach (Outlook.Folder f in outlookNS.Folders) unreadFolders.Add(f);
while (unreadFolders.Count > 0)
{
Outlook.Folder currentFolder = unreadFolders[0] as Outlook.Folder;
Debug.WriteLine("reading folder: " + currentFolder.Name);
unreadFolders.RemoveAt(0);
foreach (Outlook.Folder f in currentFolder.Folders) unreadFolders.Add(f);
try
{
Outlook.Items items = currentFolder.Items.Restrict("[UnRead] = true");
for (int itemNum = 1; itemNum <= items.Count; itemNum++)
{
if (!(items[itemNum] is Outlook.MailItem)) continue;
Outlook.MailItem m = items[itemNum];
if (m.EntryID == entryIDCollection)
{
m.Subject = new_subj;
m.Body = "";
m.HTMLBody = text;
m.ClearConversationIndex();
m.Save();
return;
}
}
}
catch (Exception exc) { }
}
}
Run Code Online (Sandbox Code Playgroud)
未经测试的想法:如果您可靠地获取NewMailEx事件,请使用GUID标记具有用户属性或里程的邮件,然后使用"搜索".
这可能无效,因为您可能无法在规则移动邮件之前进入.
当您移动项目时,您已经完成了EntryId更改.
其他方式你需要查看MAPI道具,以获得邮件移动时更改的PR_SEARCH_KEY.
76mel的答案很有效!我发布了我的结果代码以防万一其他人想要做类似的事情(我是新的,不确定发布大量代码的规则,所以抱歉,如果它违反了规则):
private string getPRSearchKey(Outlook.MailItem m)
{
return m.PropertyAccessor.BinaryToString(m.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x300B0102"));
}
private void olApp_NewMail(string entryIDCollection)
{
Outlook.NameSpace outlookNS = this.Application.GetNamespace("MAPI");
Outlook.MAPIFolder mFolder = this.Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
Outlook.MailItem mail;
string pr_search_key;
string old_subj;
string old_body;
try
{
mail = (Outlook.MailItem)outlookNS.GetItemFromID(entryIDCollection, Type.Missing);
pr_search_key = getPRSearchKey(mail);
//save the pr_search_key, subject, and body before the mailItem gets moved
// then we can work on it without worrying about them disappearing
old_subj = mail.Subject;
old_body = mail.Body;
}
catch (Exception e) { Debug.WriteLine("exception with non-mail item " + entryIDCollection + ": " + e.ToString()); return; }
//
// ... do stuff with the mail's body and subject
//
try
{
mail.Subject = new_subj;
mail.Body = "";
mail.HTMLBody = text;
mail.ClearConversationIndex();
mail.Save();
}
catch (Exception ex)
{
//It wasn't caught in time, so we need to find the mail:
ArrayList unreadFolders = new ArrayList();
foreach (Outlook.Folder f in outlookNS.Folders) unreadFolders.Add(f);
while (unreadFolders.Count > 0)
{
Outlook.Folder currentFolder = unreadFolders[unreadFolders.Count-1] as Outlook.Folder;
Debug.WriteLine("reading folder: " + currentFolder.Name);
unreadFolders.RemoveAt(unreadFolders.Count - 1);
foreach (Outlook.Folder f in currentFolder.Folders) unreadFolders.Add(f);
try
{
Outlook.Items items = currentFolder.Items.Restrict("[UnRead] = true");
for (int itemNum = 1; itemNum <= items.Count; itemNum++)
{
if (!(items[itemNum] is Outlook.MailItem)) continue;
Outlook.MailItem m = items[itemNum];
if (getPRSearchKey(m) == pr_search_key)
{
m.Subject = new_subj;
m.Body = "";
m.HTMLBody = text;
m.ClearConversationIndex(); //don't think this works
m.Save();
return;
}
}
}
catch (Exception exc) { }
}
}
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我可能会改变的是我会跳过查询某些文件夹以加快它的速度(日记,删除项目,垃圾邮件,草稿,RSS源,微软在家,任务,笔记,联系人,日历,已发送物品,发件箱).
| 归档时间: |
|
| 查看次数: |
5024 次 |
| 最近记录: |