Receiving all events twice in Excel COM add in

Jan 27 at 4:23 PM
I am a new user to NetOffice. I am really impressed with what you have done with wrapping COM objects and version independence.

I think I must be adding my event handlers wrong because I am receiving all events twice in my handlers. I have tried two techniques but am getting the same result.

First technique (AddHandler):
Public Class Addin
   Inherits Excel.Tools.COMAddin

    Public Sub New()
        Dim onStartupCompleteHandler As OnStartupCompleteEventHandler = AddressOf Me.Addin_OnStartupComplete
        AddHandler Me.OnStartupComplete, onStartupCompleteHandler
    End Sub

    Private Sub Addin_OnStartupComplete(ByRef custom As System.Array) Handles Me.OnStartupComplete
        Dim application_WorkbookActivateEventHandler As Excel.Application_WorkbookActivateEventHandler = AddressOf Me.Addin_Application_WorkbookActivateEventHandler
        AddHandler Application.WorkbookActivateEvent, application_WorkbookActivateEventHandler
         Debug.WriteLine($"Addin started in Excel Version {Application.Version}")
    End Sub

    Private Sub Addin_Application_WorkbookActivateEventHandler(Wb As Excel.Workbook)
        Debug.WriteLine($"Workbook {Wb.Name} activated.")
    End Sub
End Class
Second technique (WithEvents):
Public Class Addin
   Inherits Excel.Tools.COMAddin

    Dim _Events As ApplicationEvents
    Public Sub New()
        Dim onStartupCompleteHandler As OnStartupCompleteEventHandler = AddressOf Me.Addin_OnStartupComplete
        AddHandler Me.OnStartupComplete, onStartupCompleteHandler
    End Sub

    Private Sub Addin_OnStartupComplete(ByRef custom As System.Array) Handles Me.OnStartupComplete
       _Events = New ApplicationEvents(Application)
        Debug.WriteLine($"Addin started in Excel Version {Application.Version}")
    End Sub
End Class

Public Class ApplicationEvents

    Private WithEvents _Application As Excel.Application

    Public Sub New(application As Excel.Application)
        If application Is Nothing Then Throw New ArgumentNullException(NameOf(application))
        _Application = application
    End Sub

    Private Sub Addin_Application_WorkbookActivateEventHandler(Wb As Excel.Workbook) Handles _Application.WorkbookActivateEvent
        Debug.WriteLine($"Workbook {Wb.Name} activated.")
    End Sub
End Class
This StackOverflow answer http://stackoverflow.com/a/30895082/3175562 got me thinking that I might be adding my handler when it is already linked, thus my handler would be getting called twice, but that doesn't really make sense. Even the onStartupCompleteHandler is getting called twice.

Thanks for any insight you guys can provide.
Coordinator
Jan 28 at 11:07 AM
This is strange. I never face a problem like this all the years,
Let me say, there is no indicator in the QA tests and examples that NetOffice raise an event 2 times.
(Try the NetOffice excel vb event example to see the event comes twice)

(I see one possible error here related to multiple loaded addins: Excel identify addins by the first 8 character of the assembly name. If you have more addins loaded with the same 8 chars at the beginning - you may face issues here)

*Sebastian
Jan 30 at 7:00 PM
Edited Jan 30 at 7:02 PM
The samples in the "\NetOffice 1.7.3\NET 4.0\Examples\Excel\VB\NetOffice COMAddin Examples" directory work correctly. I believe I was misled by the project created by the "New Project Wizard" contained in the "Developers Toolbox" application that you provide. Among the classes created by that wizard, the constructor of the Addin object adds the event handlers for the events OnStartupComplete and OnDisconnection.
Public Class Addin
   Inherits Excel.Tools.COMAddin

    Public Sub New()

        Dim onStartupCompleteHandler As OnStartupCompleteEventHandler = AddressOf Me.Addin_OnStartupComplete
        AddHandler Me.OnStartupComplete, onStartupCompleteHandler

        Dim onDisconnection As OnDisconnectionEventHandler = AddressOf Me.Addin_OnDisconnection
        AddHandler Me.OnDisconnection, onDisconnection

    End Sub
Based on reading the other samples, it looks like the the constructor of the add-in should be empty. The NetOffice COMAddin class already implements IDTExtensibility2 and apparently the Addin_OnStartupComplete is already wired up to handle the event when you inherit from the COMAddin class. When the constructor was adding a handler, it was really adding a second one. That is why the OnStartupComplete handler was running twice. That routine running twice was then adding handlers for other events twice, doubling up their handler count (which can be seen in the private fields of the NetOffice Application object).

When I remove these lines from the constructor, the doubling up disappears. I post this fix to clarify to others that may be mystified why this happens. I do think it would be good if you could update the wizard to not add those extra handlers. Thanks.
Coordinator
Feb 1 at 4:12 PM
Hmm...

I can create the event routing in the .vb designer file(in code generation by toolbox). This miss a bit of transparence what if find.
On the other hand, this helps to avoid run into this trap.
(in summary, your suggestion is the better one in 65/35% advantage/disadvantage. on my todo list now)

*Sebastian
Aug 31 at 7:54 AM
Hi there,

I'm facing the same issue with a PowerPoint add-in.
This is what I have in constructor and Addin_OnStartupComplete event is firing twice when I open two pptx files IF the second file is opened by double clicking on it in Windows explorer (it doesn't happen if the second file is opened through File -> Open menu in PowerPoint):
        public Addin()
        {
            this.OnStartupComplete += new OnStartupCompleteEventHandler(Addin_OnStartupComplete);
            this.OnDisconnection += new OnDisconnectionEventHandler(Addin_OnDisconnection);
        }
Removing the event handlers for the events OnStartupComplete and OnDisconnection from the constructor didn't worked for me (as it did for Michael in Excel), in my case the Addin_OnStartupComplete event is not fired at all.
I fixed this by implementing a condition to process the Addin_OnStartupComplete event only the first time. Not the best solution, but it's working.

Adrian