2017-03-08 2 views
1

Je crée un complément Outlook pour suivre le traitement du courrier à partir de la boîte aux lettres. Suis les dossiers et les éléments (en y ajoutant des événements) et les stocke dans une liste locale pour éviter que le GC ne supprime tous les événements après la première exécution. Cependant, l'événement d'ajout de dossier ne se déclenche qu'une fois. Je ne sais pas quel est le problème.Outlook 2016 Dossier VSTO Ajouter un feu d'événement une seule fois

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml.Linq; 
using OutlookNS = Microsoft.Office.Interop.Outlook; 
using Office = Microsoft.Office.Core; 
using System.Net; 
using System.Windows.Forms; 


namespace OutlookAuditor 
{ 
    public partial class ThisAddIn 
    { 
     #region private variables 

     OutlookNS._NameSpace outNS; 
     OutlookNS.Explorer explorer; 
     string profileName = string.Empty; 
     List<SuperMailFolder> wrappedFolders = new List<SuperMailFolder>(); 
     Logger logger = new Logger(); 
     SuperMailFolder folderToWrap; 
     #endregion 

     private void ThisAddIn_Startup(object sender, System.EventArgs e) 
     { 
      try 
      { 
       OutlookNS.Application application = this.Application; 

       //Get the MAPI namespace 
       outNS = application.GetNamespace("MAPI"); 
       //Get UserName 
       string profileName = outNS.CurrentUser.Name; 

       //Create a new outlook application 
       //I had to do this because my systems default mail box was ost file other just the below commented line is enough 
       //OutlookNS.MAPIFolder inbox = outNS.GetDefaultFolder(OutlookNS.OlDefaultFolders.olFolderInbox) as OutlookNS.MAPIFolder; 
       OutlookNS.MAPIFolder inbox; 
       OutlookNS.Folders folders = outNS.Folders; 
       OutlookNS.MAPIFolder selectedFolder = null; 
       if (folders.Count > 1) 
       { 

        List<string> folderNames = new List<string>(); 
        foreach (OutlookNS.Folder folder in folders) 
        { 
         folderNames.Add(folder.Name); 
        } 
        using (selectMailBox frmSelect = new selectMailBox(folderNames)) 
        { 

         if (DialogResult.OK == frmSelect.ShowDialog()) 
         { 
          selectedFolder = folders[frmSelect.SelectedFolder]; 
         } 
        } 


       } 
       else 
       { 
        selectedFolder = folders[1]; 
       } 
       logger.SaveLog("Folder Selected " + selectedFolder.Name); 
       inbox = selectedFolder.Folders["Inbox"];//as OutlookNS.MAPIFolder; 
       //Create a super mail folder 
       folderToWrap = new SuperMailFolder(inbox, profileName); 
       wrappedFolders.Add(folderToWrap); 
       wrappedFolders.AddRange(folderToWrap.wrappedSubFolders); 

       //System.Runtime.InteropServices.Marshal.ReleaseComObject(inbox); 
      } 
      catch (Exception ex) 
      { 
       logger.WriteException(ex); 
      } 
      finally 
      { 

      } 
     } 

     private void ThisAddIn_Shutdown(object sender, System.EventArgs e) 
     { 
     } 

     #region VSTO generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InternalStartup() 
     { 
      this.Startup += new System.EventHandler(ThisAddIn_Startup); 
      this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown); 
     } 

     #endregion 
    } 

    #region SuperMailItem object 
    class SuperMailItem 
    { 
     //local variable for avoiding GC invocation 
     OutlookNS.MailItem item; 
     string _profileName; 
     OutlookAuditor.Common.AuditItem auditItem; 
     string parentMailID; 
     string _folderName = string.Empty; 
     OutlookNS.MailItem replyItem; 
     Logger logger = new Logger(); 
     //constructor that wraps mail item with required events 
     internal SuperMailItem(OutlookNS.MailItem MailItemToWrap, string profileName,string folderName) 
     { 
      try 
      { 
       item = MailItemToWrap as OutlookNS.MailItem; 

       _folderName = folderName; 
       if (item is OutlookNS.MailItem) 
       { 
        logger.SaveLog(item.Subject); 
        item.PropertyChange += MailItemToWrap_PropertyChange; 
        //item.PropertyChange += new OutlookNS.ItemEvents_10_PropertyChangeEventHandler(MailItemToWrap_PropertyChange); 

        ((OutlookNS.ItemEvents_10_Event)item).Reply += SuperMailItem_Reply; 
       } 
      } 
      catch(Exception ex) 
      { 
       logger.WriteException(ex,"SuperMailItem Constructor"); 
      } 

     } 

     void SuperMailItem_Reply(object Response, ref bool Cancel) 
     { 
      try 
      { 
       parentMailID = string.Empty; 
       replyItem = Response as OutlookNS.MailItem; 
       ((OutlookNS.ItemEvents_10_Event)replyItem).Send += SuperMailItem_Send; 
      } 
      catch(Exception ex) 
      { 
       logger.WriteException(ex); 
      } 

     } 


     //this event is not firing 
     void SuperMailItem_Send(ref bool Cancel) 
     { 
      try 
      { 
       if (!Cancel) 
       { 
        createAuditItem(); 
        auditItem.ActionDescription = "REPLY_SENT"; 
        SaveLog(); 
       } 
      } 
      catch(Exception ex) 
      { 
       logger.WriteException(ex); 
      } 

     } 

     //property change event- fires when any property of a mail item changes 
     void MailItemToWrap_PropertyChange(string Name) 
     { 
      try 
      { 

       createAuditItem(); 
       //We are interested in UnRead property, if this property changes audit. 
       if (Name == "UnRead") 
       { 
        if (!item.UnRead) 
        { 
         auditItem.ActionDescription = "MAIL_READ"; 
        } 
        else 
        { 
         auditItem.ActionDescription = "MAIL_UNREAD"; 
        } 
       } 
       SaveLog(); 
      } 
      catch(Exception ex) 
      { 
       logger.WriteException(ex); 
      } 
     } 

     void createAuditItem() 
     { 
      auditItem = new Common.AuditItem(); 
      auditItem.ActionTimestamp = DateTime.Now; 
      auditItem.EntryID = item.EntryID; 
      auditItem.ProfileName = _profileName; 
      auditItem.ReceivedTimestamp = item.ReceivedTime; 
      auditItem.SystemIP = Helper.SystemIP(); 
      auditItem.UserName = Helper.UserID(); 
      auditItem.OriginalMailSentBy = item.Sender.Name; 
      auditItem.FolderName = _folderName; 
      auditItem.Subject = item.Subject; 
     } 

     void SaveLog() 
     { 
      Logger logger = new Logger(); 
      logger.Save(auditItem); 
     } 
    } 

    #endregion 

    #region SuperMailFolder object 
    class SuperMailFolder 
    { 
     #region private variables 
     OutlookNS.MAPIFolder _wrappedFolder; 
     string _profileName; 
     List<SuperMailItem> wrappedItems = new List<SuperMailItem>(); 
     public List<SuperMailFolder> wrappedSubFolders = new List<SuperMailFolder>(); 
     string folderName = string.Empty; 
     Logger logger = new Logger(); 
     #endregion 

     #region constructor 
     internal SuperMailFolder(OutlookNS.MAPIFolder folder, string profileName) 
     { 
      try 
      { 
       //assign it to local private master 
       _wrappedFolder = folder; 
       folderName = folder.Name; 
       _profileName = profileName; 
       //assign event handlers for the folder 
       _wrappedFolder.Items.ItemAdd +=Items_ItemAdd; 
       _wrappedFolder.Items.ItemRemove += Items_ItemRemove; 

       refreshItemList(); 

       //Go through all the subfolders and wrap them as well 
       foreach (OutlookNS.MAPIFolder tmpFolder in _wrappedFolder.Folders) 
       { 
        logger.SaveLog("Wrapping folder " + tmpFolder.Name); 
        SuperMailFolder tmpWrapFolder = new SuperMailFolder(tmpFolder, _profileName); 
        wrappedSubFolders.Add(tmpWrapFolder); 
        wrappedSubFolders.AddRange(tmpWrapFolder.wrappedSubFolders); 
       } 

      } 
      catch(Exception ex) 
      { 
       logger.WriteException(ex); 
      } 
     } 
     #endregion 

     void Items_ItemRemove() 
     { 
      refreshItemList(); 
     } 

     #region Handler of addition item into a folder 
     void Items_ItemAdd(object Item) 
     { 
      try 
      { 
       if (Item is OutlookNS.MailItem) 
       { 

        OutlookNS.MailItem item = Item as OutlookNS.MailItem; 

        wrappedItems.Add(new SuperMailItem(item, _profileName, folderName)); 
        logger.SaveLog("Adding new item. New collection count:" + wrappedItems.Count.ToString()); 
        OutlookAuditor.Common.AuditItem auditItem = new Common.AuditItem(); 
        auditItem.ActionTimestamp = DateTime.Now; 
        auditItem.EntryID = item.EntryID; 
        auditItem.ProfileName = _profileName; 
        auditItem.ReceivedTimestamp = item.ReceivedTime; 
        auditItem.SystemIP = Helper.SystemIP(); 
        auditItem.UserName = Helper.UserID(); 
        auditItem.ActionDescription = "FOLDER_ADD"; 
        auditItem.FolderName = folderName; 
        auditItem.OriginalMailSentBy = item.Sender.Name; 
        auditItem.Subject = item.Subject; 
        logger.Save(auditItem); 
       } 
      } 
      catch(Exception ex) 
      { 
       logger.WriteException(ex); 
      } 
     } 

     void refreshItemList() 
     { 

      try 
      { 
       wrappedItems.Clear(); 
       wrappedItems = new List<SuperMailItem>(); 
       logger.SaveLog("Wrapping items in " + folderName); 
       //Go through all the items and wrap it. 
       foreach (OutlookNS.MailItem item in _wrappedFolder.Items) 
       { 
        try 
        { 
         if (item is OutlookNS.MailItem) 
         { 
          OutlookNS.MailItem mailItem = item as OutlookNS.MailItem; 
          SuperMailItem wrappedItem = new SuperMailItem(mailItem, _profileName, folderName); 
          wrappedItems.Add(wrappedItem); 
         } 
        } 
        catch (Exception ex) 
        { 
         logger.WriteException(ex); 
        } 
       } 
       logger.SaveLog("Wrapped items in " + folderName + ":" + wrappedItems.Count.ToString()); 
      } 
      catch(Exception ex) 
      { 
       logger.WriteException(ex); 
      } 
     } 
     #endregion 
    } 
    #endregion 

    static class Helper 
    { 
     public static string SystemIP() 
     { 
      string hostName = Dns.GetHostName(); 
      string hostAddress = Dns.GetHostByName(hostName).AddressList[0].ToString(); 
      return hostAddress; 
     } 

     public static string UserID() 
     { 
      return System.Security.Principal.WindowsIdentity.GetCurrent().Name; 
     } 
    } 
} 

Répondre

3

Le code suivant est le problème:

 _wrappedFolder.Items.ItemAdd +=Items_ItemAdd; 
     _wrappedFolder.Items.ItemRemove += Items_ItemRemove; 

L'objet qui déclenche les événements doivent être en vie - dans votre cas, vous configurez un gestionnaire d'événements sur une variable implicite de retour des _wrappedFolder.Items property - dès que le GC libère cette variable implicite, aucun événement ne se déclenche. Déclarez l'objet Items au niveau de la classe pour vous assurer qu'il reste référencé et actif.

+0

merci compagnon. Cela a fait l'affaire – Ramki

+0

m'a aidé aussi. Les problèmes du GC sont difficiles. – Roland