2010-02-20 61 views
8

我正在爲Outlook 2007創建一個插件,用於在收到郵件時讀取郵件,然後重寫它。該插件很好,並重寫郵件的項目沒有一個Outlook規則,將他們移動到另一個文件夾。如果有規則,大約50%的時間仍然沒有問題。另外50%的時間,規則在我的插件完成之前移動郵件項目。我得到以下錯誤:VSTO:在Outlook規則移動郵件之前使用newmailex處理郵件

"The operation cannot be performed because the object has been deleted."

我使用NewMailEx事件打電話給我重寫功能:

private void ThisAddIn_Startup(object sender, System.EventArgs e) 
{ 
    this.Application.NewMailEx += new Outlook.ApplicationEvents_11_NewMailExEventHandler(olApp_NewMail); 
} 

在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; } 

我以爲我可以藉此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) { } 
      } 

     } 

回答

5

未經檢驗的想法:如果你確實得到NewMailEx事件,與用戶的財產或里程以GUID標記郵件然後使用搜索。

這可能不起作用,因爲在規則移動郵件之前您可能無法進入。

正如您已經計算出項目移動時的EntryId更改。

其他方式您需要查看MAPI道具以獲取在郵件移動時劑量發生變化的PR_SEARCH_KEY。

+1

太棒了,就是這樣!當我收到消息時,我已經抓住了PR_SEARCH_KEY。我也抓住了身體和主題。然後我修改了主題和身體。當我嘗試更新身體/主題並且失敗時,我會通過搜索文件夾並找到匹配的郵件。雖然如果複製郵件項目(兩個副本可能共享相同的PR_SEARCH_KEY),PR_SEARCH_KEY不是唯一的,但這非常好,因爲當它發生時,我還沒有製作任何副本。 我試圖投票了,但我太新了投票:(我會發布我的代碼下面(用盡評論字符) – mdiehl13 2010-02-21 02:17:51

5

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) { } 
     } 

    } 
} 

順便說一句, (日記,已刪除郵件,垃圾郵件,草稿,RSS源,Microsoft在家中,任務,便箋,聯繫人,日曆,已發送郵件等)可能會改變的一個方面是我會跳過查詢某些文件夾以加快速度發件箱)。

+0

此外,有時當我得到newmailex郵件已被移動(發現此我修改了我的第一個catch語句,這樣如果pr_search_key ==「」,抓住所有未讀的郵件項目,並且看看我是否修改了它們......這很煩人。 我看到的另一個問題是,當我的電腦退出睡眠狀態時,收到的任何新電子郵件都不會發送newmailex,因此所有這些郵件都會丟失。很煩人 – mdiehl13 2010-02-25 00:24:28

+0

這個答案很舊,但你還在使用這個嗎? http://schemas.microsoft.com/mapi/proptag/0x300B0102似乎沒有工作了。 – Jimmy 2018-01-21 16:16:44

+0

不,對不起。當我改變公司時,我停止使用這些年前。對不起,我忍不住 – mdiehl13 2018-01-22 18:09:23

相關問題