Am creating a outlook add-in to track mail processing from mailbox. Am wrapping the folders and the items(adding some events into it ) and storing them in a local list to avoid GC clearing all the events after first execution. However still the folder add event only fires once. Not sure what is the problem.
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;
}
}
}
The following code is the problem:
_wrappedFolder.Items.ItemAdd +=Items_ItemAdd;
_wrappedFolder.Items.ItemRemove += Items_ItemRemove;
The object that fires the events must be alive - in your case you set up an event handler on an implicit variable returned from the _wrappedFolder.Items property - as soon as the GC releases that implicit variable, no events will fire. Declare the Items object on the class level to make sure it stays referenced and alive.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.