Estoy creando un complemento para Outlook 2007 que lee un elemento de correo cuando se recibe y luego lo reescribe. El complemento funciona muy bien y reescribe el correo para los elementos que no tienen una regla de Outlook que los mueve a otra carpeta. Si hay una regla, todavía está bien aproximadamente el 50% del tiempo. El otro 50% de las veces, la regla mueve el elemento de correo antes de que termine mi complemento. Me sale el siguiente error:VSTO: procesar el correo utilizando newmailex antes de que las reglas de Outlook muevan el correo
"The operation cannot be performed because the object has been deleted."
estoy usando evento NewMailEx a llamar a mi función de reescritura:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.NewMailEx += new Outlook.ApplicationEvents_11_NewMailExEventHandler(olApp_NewMail);
}
En Outlook 2007, NewMailEx da una entryID para el correo. Este entryID se utiliza inicialmente para averiguar qué objeto de correo para utilizar:
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; }
pensé que podía tomar esta entryID (que funciona el código anterior), e iterar a través de todos mis carpetas (en el intercambio, así como en mi computadora) buscando la misma identificación de correo. Cuando finalmente repito hasta donde está el correo, el EntryID del correo movido es muy diferente al entryIDCollection.
Tal vez estoy haciendo esto de la manera incorrecta. ¿Alguien sabe cómo evitar que el evento se propague hasta que termine o cómo rastrear el correo electrónico movido?
Aquí está mi código para recorrer las carpetas por si alguien tiene curiosidad:
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) { }
}
}
Genial, ¡eso fue todo! Lo hice agarrar el PR_SEARCH_KEY a la derecha cuando llegó el mensaje. También agarré el cuerpo y el sujeto. Luego modifiqué el sujeto y el cuerpo. Cuando intento actualizar el cuerpo/asunto y falla, lo hago buscar entre las carpetas y encuentro el correo correspondiente. Aunque PR_SEARCH_KEY no es único SI se copia el elemento de correo (ambas copias pueden compartir el mismo PR_SEARCH_KEY), eso está perfectamente bien, porque cuando aparece, todavía no he hecho ninguna copia. Traté de votar esto, pero soy muy nuevo para votar :(Voy a publicar mi código a continuación (sin carácteres de comentarios) – mdiehl13