Solved

Problem with VSTO event handler going out of scope in Outlook AddIn

Posted on 2011-09-13
19
1,653 Views
Last Modified: 2013-11-10
I have the enclosed code and am trying to hook up the attachment events within the Inspector. These delegate handlers (eg gp2_fnAttachAdd) do not fire when I try to attach a file to an item:

            ((Outlook.ItemEvents_10_Event)Inspector).AttachmentAdd += new Outlook.ItemEvents_10_AttachmentAddEventHandler(gp2_fnAttachAdd);
            ((Outlook.ItemEvents_10_Event)Inspector).AttachmentRemove += new Outlook.ItemEvents_10_AttachmentRemoveEventHandler(gp2_fnAttachDel);

I am assuming that this is because the handlers go out of scope, although other handlers that are in the same block seem to remain in scope. I am quite new to C# and am struggling with how the garbage collection functions for this area. I enclose the AddIn c# file and the wrapper from where the delegate handlers are declared.

Any assistance on this would be very greatly appreciated, please treat me as a newbie :)


 ThisAddIn.cs InspectorWrapper.cs
0
Comment
Question by:spanout
  • 10
  • 9
19 Comments
 
LVL 35

Expert Comment

by:Miguel Oz
ID: 36534346
Create a variable to hold your event instance for the lifetime of the add-in
public partial class ThisAddIn
{
   Outlook.ApplicationEvents_11_ItemSendEventHandler myHandler;
   //Your existing code...
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            myHandler = new Outlook.ApplicationEvents_11_ItemSendEventHandler(gp2_fnItemSend);
            this.Application.ItemSend += myHandler;
           //Your existing code...

         }
   //Your existing code...

}

In interop scenarios, you need a field variable to avoid the garbage collector to free up your handler.
0
 

Author Comment

by:spanout
ID: 36560604
Hi mas oz2003.

I have tried you solution and it will not handle the envent. This is what I did, please forgive me if it is wrong:

I added the following public statements in thisaddin:

 public partial class ThisAddIn
    {
        public Outlook.ItemEvents_10_AttachmentAddEventHandler myAttachHandler;
        public Outlook.ItemEvents_10_AttachmentRemoveEventHandler myDetachHandler;

I added my handlers in the same class

  void gp2_fnAttachFile(Outlook.Attachment myAttach)
        {
            attachcount++;
        }

        void gp2_fnDetachFile(Outlook.Attachment myAttach)
        {
            attachcount--;
        }
In my inspector wrapper, I added these:
            ((Outlook.ItemEvents_10_Event)Inspector).AttachmentAdd += Globals.ThisAddIn.myAttachHandler;
            ((Outlook.ItemEvents_10_Event)Inspector).AttachmentRemove += Globals.ThisAddIn.myDetachHandler;


When I run the addin, I can see that it is connecting the handlers, but when I attach a file, it does not fire my custom handler. Can you see what I have done wrong?

Thanks for your help


0
 
LVL 35

Expert Comment

by:Miguel Oz
ID: 36563916
My posted code solved your issue in the ThisAddIn class only.

Your custom handler instance has to be created in the same class that are used. You are trying to call global handlers; if needed you need to pass them as parameters.

In you case at ConnectEvents method you must have all handlers as class instance and assign the instance to your handlers. Also the wrapper class must exist for the lifetime of the Add-in.
0
 

Author Comment

by:spanout
ID: 36566774
Thanks for your suggestions. I have moved everything into the ThisAddIn class so there is no longer a reliance on the wrapper class. The Itemsend event works perfectly, but the handlers for Attachments still seem to be going through GC:
I created the variables for the 2 handlers, atached them to the Inspectors as they are created. I run this in debug and when I open a mail item, this code runs but it never runs the gp2_fnAttachFile function when I add an attachment. Surely having everything in the ThisAddIn class keeps it alive while the mailitem is open. This certainly is the case with the send handler which works perfectly. Again, any help is appreciated, I feel stupid not being able to grasp this :(




public partial class ThisAddIn
    {
        Outlook.Inspectors _Inspectors;
        Outlook.Explorers _Explorers;

        Outlook.MailItem mailItem;
        Outlook.ItemEvents_10_AttachmentAddEventHandler myAttachHandler;
        Outlook.ItemEvents_10_AttachmentRemoveEventHandler myDetachHandler;

        Dictionary<Guid, WrapperClass> _WrappedObjects;
        public bool IsLicensed = true;
        public string Licensor = "";
        public string ExpireDate = "";
        public int attachcount = 0;
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {




            myAttachHandler = new Outlook.ItemEvents_10_AttachmentAddEventHandler(gp2_fnAttachFile);
            myDetachHandler = new Outlook.ItemEvents_10_AttachmentRemoveEventHandler(gp2_fnDetachFile);
         






            #region license check

            if (Properties.Settings.Default.Licence != "")
            {
                olicense myLicence = new olicense();
                oOutlookUtilities mysender = new oOutlookUtilities();
                
                myLicence.AccountEMail = Convert.ToString(mysender.getSenderAddress()[0]);
                myLicence.key = Properties.Settings.Default.Licence;
                myLicence.decodeLicense();
                if (myLicence.Error != "")
                {
                    MessageBox.Show("There was an error starting OutlookGuard: " + myLicence.Error);
                    IsLicensed = false;
                }
                else
                {
                    Licensor = myLicence.UserName;
                    if (myLicence.warningdays > 370) { ExpireDate = "Perpetual"; }
                    if (myLicence.warningdays < 370) { ExpireDate = Convert.ToString(myLicence.ExpiresDate).Split(' ')[0]; }

                }

                myLicence = null;
                mysender = null;
            }
            else
            {
                MessageBox.Show("This product is unregistered. Please go to the OutlookGuard website to obtain a license key, and enter the key in the settings area.");

            }

            #endregion
            
            

            this.Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(gp2_fnItemSend);
           
            
            _WrappedObjects = new Dictionary<Guid, WrapperClass>();


            _Inspectors = this.Application.Inspectors;
            _Inspectors.NewInspector += new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(_Inspectors_NewInspector);
            
            // Are there any open Inspector after Startup ?        
            for (int i = _Inspectors.Count; i >= 1; i--)
            {
                // Wrap the Inspector and do some usefull with it            
                WrapInspector(_Inspectors[i]);
                if (_Inspectors[i] is Outlook.MailItem)
                {
                    
                }

            }
            
            // Explorer stuff        
            _Explorers = this.Application.Explorers;
            // Are there any open Explorers after Startup ?        
            for (int i = _Explorers.Count; i >= 1; i--)
            {
                // Wrap the Explorer and do some usefull with it            
                WrapExplorer(_Explorers[i]);
            }
            
            _Explorers.NewExplorer += new Microsoft.Office.Interop.Outlook.ExplorersEvents_NewExplorerEventHandler(_Explorers_NewExplorer);
        }


        #region event handlers


        void gp2_fnAttachFile(Outlook.Attachment myAttach)
        {
            attachcount++;
        }

        void gp2_fnDetachFile(Outlook.Attachment myAttach)
        {
            attachcount--;
        }

        void gp2_fnItemSend(object item, ref bool cancel)
        {

            if (IsLicensed == true) // do not function if not licensed
            {
                oOutlookGuardActions myActions = new oOutlookGuardActions();
                if (item is Outlook.MailItem)
                {
                    myActions.RecipientList = (item as Outlook.MailItem).Recipients;
                    myActions.sSubject = (item as Outlook.MailItem).Subject;
                    myActions.sBody = (item as Outlook.MailItem).Body;
                    myActions.AttachList = (item as Outlook.MailItem).Attachments;


                    cancel = myActions.performcheck();
                    (item as Outlook.MailItem).DeferredDeliveryTime = DateTime.Now.AddSeconds(myActions.delaysend);
                    (item as Outlook.MailItem).Subject = myActions.sSubject;


                    myActions = null;

                }
            }
        }


        #endregion








        #region wrapper classes

        void _Explorers_NewExplorer(Microsoft.Office.Interop.Outlook.Explorer Explorer)
        {
            WrapExplorer(Explorer);
        }
        
        void WrapExplorer(Microsoft.Office.Interop.Outlook.Explorer Explorer)
        {
            ExplorerWrapper wrappedExplorer = new ExplorerWrapper(Explorer);
            wrappedExplorer.Closed += new WrapperClosedDelegate(wrappedObject_Closed);
            _WrappedObjects[wrappedExplorer.Id] = wrappedExplorer;
        }

        
        void _Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
        {
            //InspectorWrapper wrappedInspector = new InspectorWrapper(Inspector);
            //wrappedInspector.Closed += new WrapperClosedDelegate(wrappedObject_Closed);
            //WrappedObjects[wrappedInspector.Id] = wrappedInspector;

            (Inspector as Outlook.MailItem).AttachmentAdd += myAttachHandler;
            (Inspector as Outlook.MailItem).AttachmentRemove += myDetachHandler;
            
            
            //

        }

Open in new window

0
 

Author Comment

by:spanout
ID: 36566893
I have updated code below which is cleaner to look at
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using System.Windows.Forms;
using System.Collections;

namespace OutlookAddIn1
{

    
    public partial class ThisAddIn
    {
        Outlook.Inspectors _Inspectors;
        Outlook.Explorers _Explorers;
        Outlook.MailItem mailItem;

        Outlook.ItemEvents_10_AttachmentAddEventHandler myAttachHandler;
        Outlook.ItemEvents_10_AttachmentRemoveEventHandler myDetachHandler;

   
        public bool IsLicensed = true;
        public string Licensor = "";
        public string ExpireDate = "";
        public int attachcount = 0;
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {



            
            
            

            this.Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(gp2_fnItemSend);
            _Inspectors = this.Application.Inspectors;
            _Inspectors.NewInspector += new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(_Inspectors_NewInspector);
            
           
        }


        #region event handlers


        void gp2_fnAttachFile(Outlook.Attachment myAttach)
        {
            attachcount++;
        }

        void gp2_fnDetachFile(Outlook.Attachment myAttach)
        {
            attachcount--;
        }

        void gp2_fnItemSend(object item, ref bool cancel)
        {

            //send code
        }


      
        void _Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
        {
            
            myAttachHandler = new Outlook.ItemEvents_10_AttachmentAddEventHandler(gp2_fnAttachFile);
            myDetachHandler = new Outlook.ItemEvents_10_AttachmentRemoveEventHandler(gp2_fnDetachFile);
         
            (Inspector as Outlook.MailItem).AttachmentAdd += myAttachHandler;
            (Inspector as Outlook.MailItem).AttachmentRemove += myDetachHandler;



        }

        #endregion

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
            
            _Inspectors = null;
            _Explorers = null;
        }

        #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

    }
}

Open in new window

0
 
LVL 35

Expert Comment

by:Miguel Oz
ID: 36570199
You are missing two field instances  and change  ThisAddIn_Startup method as follows:
Outlook.ApplicationEvents_11_ItemSendEventHandler mytemSendEventHandler;
Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler myNewInspectorEventHandler;

private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
             mytemSendEventHandler= new Outlook.ApplicationEvents_11_ItemSendEventHandler(gp2_fnItemSend);

            this.Application.ItemSend += mytemSendEventHandler;
            _Inspectors = this.Application.Inspectors;
            myNewInspectorEventHandler = new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(_Inspectors_NewInspector);
            _Inspectors.NewInspector += myNewInspectorEventHandler;
           
           
        }

Thus, any event handler must be created as a field instance before being assigned to any Outlook interop object. (My previous post shows an example fro one handler you have to do this construct for all event handlers that are used on your Add-in project)
0
 

Author Comment

by:spanout
ID: 36570333
sorry, I seem to be missing the point... I have the two fields set up in my code

Outlook.ItemEvents_10_AttachmentAddEventHandler myAttachHandler;
Outlook.ItemEvents_10_AttachmentRemoveEventHandler myDetachHandler;


The send function works fine, it's the attachment function that doesn't
0
 
LVL 35

Expert Comment

by:Miguel Oz
ID: 36570693
You need 4 fields:
Outlook.ApplicationEvents_11_ItemSendEventHandler mytemSendEventHandler;
Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler myNewInspectorEventHandler;
Outlook.ItemEvents_10_AttachmentAddEventHandler myAttachHandler;
Outlook.ItemEvents_10_AttachmentRemoveEventHandler myDetachHandler;

Again any event handler must be an instance.
Note: Are you creating the same handler for all inspectors (myAttachHandler) if that is the case then you need to create the instance at ThisAddIn_Startup, otherwise you are losing the reference to them every time you assign them at _Inspectors_NewInspector. Thus all event instances must be created only once at ThisAddIn_Startup
0
 

Author Comment

by:spanout
ID: 36574839
Hi mas_oz2003

I'm pretty sure that I have now understood what you have been trying to tell me (sorry for being slow :) )

Please take a look and see if it looks correct to you because the events are still not firing for gp2_fnAttachFile and gp2_fnDetachFile. As before the gp2_fnItemSend fires each time. Is it because the _Inspectors_NewInspector is creating the new handlers which gets GC?

Thanks again for your help.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using System.Windows.Forms;
using System.Collections;

namespace OutlookAddIn1
{

    
    public partial class ThisAddIn
    {




        Outlook.Inspectors _Inspectors;
        Outlook.Explorers _Explorers;
        Outlook.MailItem mailItem;

        Outlook.ItemEvents_10_AttachmentAddEventHandler myAttachHandler;
        Outlook.ItemEvents_10_AttachmentRemoveEventHandler myDetachHandler;
        Outlook.ApplicationEvents_11_ItemSendEventHandler myHandler;
        Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler myNewInspectorEventHandler;
    



   
        public bool IsLicensed = true;
        public string Licensor = "";
        public string ExpireDate = "";
        public int attachcount = 0;
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {



           


            myHandler = new Outlook.ApplicationEvents_11_ItemSendEventHandler(gp2_fnItemSend);
            this.Application.ItemSend += myHandler;


            _Inspectors = this.Application.Inspectors;

            myNewInspectorEventHandler = new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(_Inspectors_NewInspector);

            _Inspectors.NewInspector += myNewInspectorEventHandler;



        }


        #region event handlers


        void gp2_fnAttachFile(Outlook.Attachment myAttach)
        {
            attachcount++;
        }

        void gp2_fnDetachFile(Outlook.Attachment myAttach)
        {
            attachcount--;
        }

        void gp2_fnItemSend(object item, ref bool cancel)
        {

            // do something
        }


      
        void _Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
        {
            
            
            myAttachHandler = new Outlook.ItemEvents_10_AttachmentAddEventHandler(gp2_fnAttachFile);
            (Inspector as Outlook.MailItem).AttachmentAdd += myAttachHandler;

            myDetachHandler = new Outlook.ItemEvents_10_AttachmentRemoveEventHandler(gp2_fnDetachFile);
            (Inspector as Outlook.MailItem).AttachmentRemove += myDetachHandler;




        }

        #endregion

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
            
            _Inspectors = null;
            _Explorers = null;
        }

        #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

    }
}

Open in new window

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 35

Expert Comment

by:Miguel Oz
ID: 36584260
Almost there, you only missed initializing all handlers in the ThisAddIn_Startup method.
All handlers are refering to unmanaged code, thus the need to keep them alive. YOu are not slow just  do not have the experience in this area, M$ uses a different code model for Office interaction.
public partial class ThisAddIn
    {
        Outlook.Inspectors _Inspectors;
        Outlook.Explorers _Explorers;
        Outlook.MailItem mailItem;

        Outlook.ItemEvents_10_AttachmentAddEventHandler myAttachHandler;
        Outlook.ItemEvents_10_AttachmentRemoveEventHandler myDetachHandler;
        Outlook.ApplicationEvents_11_ItemSendEventHandler myHandler;
        Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler myNewInspectorEventHandler;

        public bool IsLicensed = true;
        public string Licensor = "";
        public string ExpireDate = "";
        public int attachcount = 0;
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            myHandler = new Outlook.ApplicationEvents_11_ItemSendEventHandler(gp2_fnItemSend);
            myAttachHandler = new Outlook.ItemEvents_10_AttachmentAddEventHandler(gp2_fnAttachFile);
            myDetachHandler = new Outlook.ItemEvents_10_AttachmentRemoveEventHandler(gp2_fnDetachFile);

            this.Application.ItemSend += myHandler;


            _Inspectors = this.Application.Inspectors;

            myNewInspectorEventHandler = new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(_Inspectors_NewInspector);

            _Inspectors.NewInspector += myNewInspectorEventHandler;
        }


        #region event handlers


        void gp2_fnAttachFile(Outlook.Attachment myAttach)
        {
            attachcount++;
        }

        void gp2_fnDetachFile(Outlook.Attachment myAttach)
        {
            attachcount--;
        }

        void gp2_fnItemSend(object item, ref bool cancel)
        {

            // do something
        }



        void _Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
        {
            (Inspector as Outlook.MailItem).AttachmentAdd += myAttachHandler;
            (Inspector as Outlook.MailItem).AttachmentRemove += myDetachHandler;
        }

        #endregion

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

            _Inspectors = null;
            _Explorers = null;
        }

        #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

    }

Open in new window

0
 

Author Comment

by:spanout
ID: 36585425
Hi mas_oz2003

I moved the initialization into ThisAddIn_Startup method as per your code, but the events still are not firing. Should the AttachmentAdd event fire when I select an attachment to add to the email?
0
 
LVL 35

Expert Comment

by:Miguel Oz
ID: 36590328
When you say it is not firing, does it mean you put a breakpoint inside this method (lines 38 and 43)?
you are right, we need to check that _Inspectors_NewInspector is firing, but we need an extra field and some code modifications as shown below:
       Outlook.MailItem myInspector;
        void _Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
        {
           Debug.WriteLine("_Inspectors_NewInspector started"); //this will show in your output screen in VS
           if (myInspector != null) return;
           if (!(Inspector is Outlook.MailItem)) return;
           Debug.WriteLine("_Inspectors_NewInspector attaching the mail item");          
           myInspector = Inspector;
           myInspector.AttachmentAdd += myAttachHandler;
           myInspector.AttachmentRemove += myDetachHandler;
        }

Note: Notice that code above works for a single inspector (Key idea : You need to keep a reference to your new inspector as well). If you need more that one inspector open at the time replace:
 Outlook.MailItem myInspector;
 with a list  or dictionary:
List<Outlook.MailItem> myInspectors;
and modify the method accordingly. (e.g. myInspectors.Add(myInspector))

0
 

Author Comment

by:spanout
ID: 36593401
Hi

I added the debug code and the only output that came out when opening a new mail item was:
_Inspectors_NewInspector started

It did not show the text _Inspectors_NewInspector attaching the mail item. It is returning on the test: if (!(Inspector is Outlook.MailItem))..

This is really strange ?

Thanks

0
 
LVL 35

Expert Comment

by:Miguel Oz
ID: 36594183
Strange indeed. The idea is that we only use inspector that is a Mail Item, we need to determine Inspector type.
Pleae put a break point  in that line and post what you see in Quick Watch when evaluating:
Inspector
Inspector as Outlook.MailItem
0
 

Author Comment

by:spanout
ID: 36595946
Hi

Inspector as Outlook.MailItem comes back as null. I put a watch on Inspector and show some of the data in the attached. Watch
0
 
LVL 35

Expert Comment

by:Miguel Oz
ID: 36699540
Ok, keep in mind that Inspector will be a Mail item only when you open mail from places like your inbox. Your original code states that only Mial items are supposed to have the new events.
In quick watch please type:
Inspector.GetType()
Check: http://www.dotnetperls.com/gettype
and post result.
0
 

Author Comment

by:spanout
ID: 36712730
GetType() returns -            
Inspector.GetType()      
{Name = "InspectorClass" FullName = "Microsoft.Office.Interop.Outlook.InspectorClass"}

This was when opening an email from inbox
0
 
LVL 35

Accepted Solution

by:
Miguel Oz earned 500 total points
ID: 36713065
Ok, you need to check:
void _Inspectors_NewInspector(Microsoft.Office.Interop.Outlook.Inspector Inspector)
        {
           Debug.WriteLine("_Inspectors_NewInspector started"); //this will show in your output screen in VS
           if (myInspector != null) return;
           if (!(Inspector.CurrentItem is Outlook.MailItem)) return;
           Debug.WriteLine("_Inspectors_NewInspector attaching the mail item");          
           (Inspector.CurrentItem as Outlook.MailItem).AttachmentAdd += myAttachHandler;
           (Inspector.CurrentItem as Outlook.MailItem).AttachmentRemove += myDetachHandler;
        }


but I think you are better off using this wrapper framework:
http://msdn.microsoft.com/en-us/library/ff973716.aspx#DevOLInspectorWrapper_CreatingWrappers

and modify it to add your required mail item event handlers. (Advantage is that it will manage the memory issues for you)
0
 

Author Closing Comment

by:spanout
ID: 36892387
mas_oz2003

Thanks for your advice. I implemented the wrapper in the link that you provided and added my own handlers in the MailItemWrapper class:

Item.AttachmentAdd += new Outlook.ItemEvents_10_AttachmentAddEventHandler(Item_Attach);
            Item.AttachmentRemove += new Outlook.ItemEvents_10_AttachmentRemoveEventHandler(Item_Detach);
            //Item.Send += new Outlook.ItemEvents_10_AttachmentRemoveEventHandler(Item_Detach);
            Item.Application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(gp2_fnItemSend);

I then added a dictionary item in ThisAddIn class to strore the attachment count for each open mailitem inspector. This works well.
        public Dictionary<Guid, int> AttachmentCount;
Thanks for your perseverance.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This article shows how to make a Windows 7 gadget that extends its U/I with a flyout panel -- a window that pops out next to the gadget.  The example gadget shows several additional techniques:  How to automatically resize a gadget or flyout panel t…
In this article, I will show how to use the Ribbon IDs Tool Window to assign the built-in Office icons to a ribbon button.  This tool will help us to find the OfficeImageId that corresponds to our desired built-in Office icon. The tool is part of…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now