2010-02-20 13 views
8

Sto creando un addon per Outlook 2007 che legge un elemento di posta quando viene ricevuto e quindi lo riscrive. L'addon funziona alla grande e riscrive la posta per gli elementi che non hanno una regola di Outlook che li sposta in un'altra cartella. Se c'è una regola, va ancora bene circa il 50% delle volte. L'altro 50% delle volte, la regola sposta l'oggetto prima che il mio addon termini. Ottengo il seguente errore:VSTO: elabora la posta utilizzando newmailex prima delle regole di Outlook sposta la posta

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

Sto usando evento NewMailEx chiamare la mia funzione di riscrittura:

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

In Outlook 2007, NewMailEx dà un entryID per la posta. Questo entryID è utilizzato inizialmente per capire quale oggetto posta elettronica da utilizzare:

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

ho pensato che avrei potuto prendere questa entryID (che funziona il codice di cui sopra), e scorrere tutte le mie cartelle (sullo scambio così come sul mio computer) cercando lo stesso ID di posta. Quando finalmente eseguo l'iterazione su dove si trova la posta, il EntryID della posta spostata è molto diverso da entryIDCollection.

Forse sto andando su questo nel modo sbagliato. Qualcuno sa come fermare la propagazione dell'evento fino a quando non ho finito, o come rintracciare l'email spostata?

Ecco il mio codice per attraversare le cartelle nel caso qualcuno di curioso:

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

     } 

risposta

5

Idea testato: Se si sta in modo affidabile ottenendo il NewMailEx Evento, segnano la posta con una proprietà utente o chilometraggio con un GUID e quindi utilizzare Cerca per quello.

Questo potrebbe non funzionare in quanto potresti non essere in grado di entrare prima che la regola sposti la posta.

Man mano che si è elaborato, il parametro EntryId viene spostato.

Altro modo è necessario esaminare gli oggetti di scena MAPI per ottenere PR_SEARCH_KEY che il dosaggio si modifica quando si sposta la posta.

+1

Ottimo, è stato così! Ho avuto afferrare la PR_SEARCH_KEY proprio quando è arrivato il messaggio. Ho anche afferrato il corpo e il soggetto. Poi ho modificato il soggetto e il corpo. Quando provo ad aggiornare il corpo/soggetto, e fallisce, allora lo faccio cercare nelle cartelle e trovare la corrispondenza corrispondente. Sebbene PR_SEARCH_KEY non sia univoco SE l'elemento di posta viene copiato (entrambe le copie possono condividere lo stesso PR_SEARCH_KEY), ciò è perfettamente corretto, perché quando viene inserito, non ho ancora fatto nessuna copia. Ho provato a votare, ma sono troppo nuovo per votare :(Pubblicherò il mio codice di seguito (a corto di caratteri di commento) – mdiehl13

5

La risposta di 76mel ha funzionato alla grande! Vi metto il mio codice risultante nel caso in cui gli altri vogliono fare qualcosa di simile (io sono nuovo e non sono sicuro circa le regole di distacco un sacco di codice, in modo scusate se è contro le regole):

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

    } 
} 

btw, qualcosa che probabilmente cambierò sarà saltare l'interrogazione di certe cartelle per accelerare un po '(Journal, Posta eliminata, Posta indesiderata, Bozze, Feed RSS, Microsoft a casa, Attività, Note, Contatti, Calendario, Posta inviata, In uscita).

+0

Inoltre, a volte quando ottengo il newmailex la posta è già stata spostata (trovato questo più tardi). Ho modificato la mia prima dichiarazione catch in modo che se pr_search_key == "", prendi tutti gli elementi di posta non letti, e vedi se li ho modificati ancora ... kind've fastidioso. Un altro problema che ho riscontrato è che quando il mio computer esce dallo stato di riposo, le nuove e-mail ricevute non inviano un nuovo messaggio, e quindi tutte queste vengono perse. Molto fastidioso – mdiehl13

+0

Questa risposta è piuttosto vecchia, ma lo stai ancora utilizzando? http://schemas.microsoft.com/mapi/proptag/0x300B0102 sembra non funzionare più. – Jimmy

+0

No, mi dispiace. Ho smesso di usarlo anni fa quando ho cambiato compagnia. Mi dispiace, non posso aiutare – mdiehl13

Problemi correlati