2017-03-08 3 views
1

Erstellt ein Outlook-Add-In zum Verfolgen der E-Mail-Verarbeitung aus dem Postfach. Wickeln Sie die Ordner und Elemente ein (fügen Sie einige Ereignisse hinzu), und speichern Sie sie in einer lokalen Liste, um zu verhindern, dass GC alle Ereignisse nach der ersten Ausführung löscht. Allerdings wird das Ereignis zum Hinzufügen eines Ordners nur einmal ausgelöst. Nicht sicher, was das Problem ist.Outlook 2016 VSTO-Ordner Ereignis hinzufügen wird nur einmal ausgelöst

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

Antwort

3

Der folgende Code ist das Problem:

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

Das Objekt, das die Ereignisse ausgelöst lebendig sein muss - in Ihrem Fall, dass Sie einen Event-Handler auf einer implizite Variable von dem _wrappedFolder.Items zurück einrichten Eigenschaft - sobald der GC diese implizite Variable freigibt, werden keine Ereignisse ausgelöst. Deklarieren Sie das Items-Objekt auf Klassenebene, um sicherzustellen, dass es referenziert und aktiv bleibt.

+0

danke mate. Das hat den Trick – Ramki

+0

hat mir auch geholfen. GC-Probleme sind schwierig. – Roland

Verwandte Themen