OnDisconnection does not fire

L

ljavis

OnConnection runs fine. I stepped through line by line and there are no
exceptions of any sort. I followed the example from "Outlook Com Add-in
for VB.NET" by microeye which I downloaded from the link in the
Microsoft's article. OnDisconnection does not happen and I also noticed
that the add in does not appear in the Tools|Options|...|COM Add-Ins...
The add-in works as far as it's been implemented with the side effect
of Outlook remaining in memory after UI is gone because add-in never
disconnects. Any ideas? This is rather urgent.

Connect looks like this:

Imports Microsoft.Office.Core
imports Extensibility
imports System.Runtime.InteropServices


#Region " Read me for Add-in installation and setup information. "
' When run, the Add-in wizard prepared the registry for the Add-in.
' At a later time, if the Add-in becomes unavailable for reasons such
as:
' 1) You moved this project to a computer other than which is was
originally created on.
' 2) You chose 'Yes' when presented with a message asking if you wish
to remove the Add-in.
' 3) Registry corruption.
' you will need to re-register the Add-in by building the
reflexionOLSetup project
' by right clicking the project in the Solution Explorer, then choosing
install.
#End Region

<GuidAttribute("CE862D54-3B61-4A79-942E-ABADE3AFDCAF"),
ProgIdAttribute("reflexionOL.Connect")> _
Public Class Connect

Implements Extensibility.IDTExtensibility2


Private OutAddInObj As OutAddIn = New OutAddIn


Public Sub OnBeginShutdown(ByRef custom As System.Array) Implements
Extensibility.IDTExtensibility2.OnBeginShutdown
End Sub

Public Sub OnAddInsUpdate(ByRef custom As System.Array) Implements
Extensibility.IDTExtensibility2.OnAddInsUpdate
End Sub

Public Sub OnStartupComplete(ByRef custom As System.Array)
Implements Extensibility.IDTExtensibility2.OnStartupComplete
End Sub


Public Sub OnConnection(ByVal application As Object, ByVal
connectMode As Extensibility.ext_ConnectMode, ByVal addInInst As
Object, ByRef custom As System.Array) Implements
Extensibility.IDTExtensibility2.OnConnection
Dim oApp As Outlook.Application
Dim oType As Type
Dim GetProgID As Object
Dim MyProgID As String
Dim oArgs As Object()

Try
'Use InvokeMember to get ProgID of addInInst object
oType = addInInst.GetType
GetProgID = oType.InvokeMember("ProgID", _
Reflection.BindingFlags.Public Or
Reflection.BindingFlags.Public Or Reflection.BindingFlags.GetField Or
Reflection.BindingFlags.GetProperty, _
Nothing, _
addInInst, _
oArgs)

MyProgID = CType(GetProgID, String)

'Convert application from generic object to
Outlook.Application
oApp = CType(application, Outlook.Application)
'Don't call InitHandler if Explorers.Count = 0 and
Inspectors.Count = 0
If oApp.Explorers.Count = 0 And oApp.Inspectors.Count = 0
Then
Exit Sub
End If
'Evaluate ConnectMode
Select Case connectMode
Case ext_ConnectMode.ext_cm_AfterStartup
Case ext_ConnectMode.ext_cm_CommandLine
Case ext_ConnectMode.ext_cm_External
Case ext_ConnectMode.ext_cm_Solution
Case ext_ConnectMode.ext_cm_Startup
Case ext_ConnectMode.ext_cm_UISetup
End Select
' Initialize COMAddin object with this connect object to
allow
' external clients to get access to exposed features
oApp.COMAddIns.Item(MyProgID.ToString).Object = Me

'Call InitHandler
Me.OutAddInobj.InitHandler(oApp, MyProgID)
Catch ex As SystemException
'DebugWriter("OnConnection Exception: {0}", ex.Message)
End Try
End Sub

Private Sub OnDisconnection(ByVal RemoveMode As
Extensibility.ext_DisconnectMode, ByRef custom As System.Array)
Implements Extensibility.IDTExtensibility2.OnDisconnection
Dim oCommandBars As Office.CommandBars
Dim oStandardBar As Office.CommandBar
Dim oCBB As CommandBarButton
Try
If RemoveMode = ext_DisconnectMode.ext_dm_UserClosed Then
'User shutdown removed COM Add-in
'Good Housekeeping requires removal of UI
oCommandBars =
Me.OutAddInObj.outlookApp.ActiveExplorer.CommandBars
'Item syntax required
oStandardBar = oCommandBars.Item("Standard")
' In case the button was not deleted, use the existing
one.
oCBB =
CType(oStandardBar.FindControl(Tag:="VB.NETSample"), CommandBarButton)
oCBB.Delete()
Else
'Host shutdown
End If
'DebugWriter("OnDisconnection Called")
OutAddInObj.UnInitHandler()
Catch ex As SystemException
'DebugWriter("OnDisconnection Exception: {0}", ex.Message)
End Try
End Sub

' Return the existing OutAddIn object to the caller
Public Function GetAddin() As OutAddIn
On Error Resume Next
Return Me.OutAddInObj
End Function



End Class


and OutAddIn like this:

Imports Microsoft.Office.Core
imports Extensibility
imports System.Runtime.InteropServices


#Region " Read me for Add-in installation and setup information. "
' When run, the Add-in wizard prepared the registry for the Add-in.
' At a later time, if the Add-in becomes unavailable for reasons such
as:
' 1) You moved this project to a computer other than which is was
originally created on.
' 2) You chose 'Yes' when presented with a message asking if you wish
to remove the Add-in.
' 3) Registry corruption.
' you will need to re-register the Add-in by building the
reflexionOLSetup project
' by right clicking the project in the Solution Explorer, then choosing
install.
#End Region

<GuidAttribute("CE862D54-3B61-4A79-942E-ABADE3AFDCAF"),
ProgIdAttribute("reflexionOL.Connect")> _
Public Class Connect

Implements Extensibility.IDTExtensibility2


Private OutAddInObj As OutAddIn = New OutAddIn


Public Sub OnBeginShutdown(ByRef custom As System.Array) Implements
Extensibility.IDTExtensibility2.OnBeginShutdown
End Sub

Public Sub OnAddInsUpdate(ByRef custom As System.Array) Implements
Extensibility.IDTExtensibility2.OnAddInsUpdate
End Sub

Public Sub OnStartupComplete(ByRef custom As System.Array)
Implements Extensibility.IDTExtensibility2.OnStartupComplete
End Sub


Public Sub OnConnection(ByVal application As Object, ByVal
connectMode As Extensibility.ext_ConnectMode, ByVal addInInst As
Object, ByRef custom As System.Array) Implements
Extensibility.IDTExtensibility2.OnConnection
Dim oApp As Outlook.Application
Dim oType As Type
Dim GetProgID As Object
Dim MyProgID As String
Dim oArgs As Object()

Try
'Use InvokeMember to get ProgID of addInInst object
oType = addInInst.GetType
GetProgID = oType.InvokeMember("ProgID", _
Reflection.BindingFlags.Public Or
Reflection.BindingFlags.Public Or Reflection.BindingFlags.GetField Or
Reflection.BindingFlags.GetProperty, _
Nothing, _
addInInst, _
oArgs)

MyProgID = CType(GetProgID, String)

'Convert application from generic object to
Outlook.Application
oApp = CType(application, Outlook.Application)
'Don't call InitHandler if Explorers.Count = 0 and
Inspectors.Count = 0
If oApp.Explorers.Count = 0 And oApp.Inspectors.Count = 0
Then
Exit Sub
End If
'Evaluate ConnectMode
Select Case connectMode
Case ext_ConnectMode.ext_cm_AfterStartup
Case ext_ConnectMode.ext_cm_CommandLine
Case ext_ConnectMode.ext_cm_External
Case ext_ConnectMode.ext_cm_Solution
Case ext_ConnectMode.ext_cm_Startup
Case ext_ConnectMode.ext_cm_UISetup
End Select
' Initialize COMAddin object with this connect object to
allow
' external clients to get access to exposed features
oApp.COMAddIns.Item(MyProgID.ToString).Object = Me

'Call InitHandler
Me.OutAddInobj.InitHandler(oApp, MyProgID)
Catch ex As SystemException
'DebugWriter("OnConnection Exception: {0}", ex.Message)
End Try
End Sub

Private Sub OnDisconnection(ByVal RemoveMode As
Extensibility.ext_DisconnectMode, ByRef custom As System.Array)
Implements Extensibility.IDTExtensibility2.OnDisconnection
Dim oCommandBars As Office.CommandBars
Dim oStandardBar As Office.CommandBar
Dim oCBB As CommandBarButton
Try
If RemoveMode = ext_DisconnectMode.ext_dm_UserClosed Then
'User shutdown removed COM Add-in
'Good Housekeeping requires removal of UI
oCommandBars =
Me.OutAddInObj.outlookApp.ActiveExplorer.CommandBars
'Item syntax required
oStandardBar = oCommandBars.Item("Standard")
' In case the button was not deleted, use the existing
one.
oCBB =
CType(oStandardBar.FindControl(Tag:="VB.NETSample"), CommandBarButton)
oCBB.Delete()
Else
'Host shutdown
End If
'DebugWriter("OnDisconnection Called")
OutAddInObj.UnInitHandler()
Catch ex As SystemException
'DebugWriter("OnDisconnection Exception: {0}", ex.Message)
End Try
End Sub

' Return the existing OutAddIn object to the caller
Public Function GetAddin() As OutAddIn
On Error Resume Next
Return Me.OutAddInObj
End Function



End Class

References include Outlook 9 and there are'nt any compile or run-time
complaints.
 
K

Ken Slovak

In general the reason that On_Disconnection won't fire is that all of your
Outlook objects haven't been released. Once they are that event should fire.
You might have to explicitly release all your objects and call the garbage
collector explicitly to get that to happen.

If the addin isn't showing up in the COM Add-Ins dialog either the addin
isn't properly registered or is registered in HKLM and not in HKCU. Addins
registered in HKLM are administrative installations that are available for
all users of that computer and addins registered there don't show up in that
dialog.
 
L

ljavis

Thanks, Ken
I'll double check the registration in HKLM vs HLCU.
Regarding the releasing the objects and GC the sample I used said that
once the On_Disconnection fired, then you need to do that. Exacly the
same code works with Outlook 2003 (Outlook 11 object library). Really,
how would you know to start cleaning up if you do not know that the
Outlook is shutting down?

Thanks
 
K

Ken Slovak

You monitor for Explorer.Close and Inspector.Close and if there are none of
either then Outlook is closing. The release of all objects has to come
before On_Disconnection because if you don't do that On_Disconnection will
never fire at all unless the user disconnects the addin using the Tools,
Options dialog. If the disconnect action is ext_dm_UserClosed then
On_Disconnection will fire even if you have objects still instantiated. If
it's ext_dm_HostShutdown it won't. That's a known bug in Outlook's COM addin
implementation.
 
L

ljavis

Thanks again.
But how do you then work around that? As I said it seems to run fine in
later versions (2003 at least). But if I want to support 2000, then
what?
 
K

Ken Slovak

Please post some of the preceding thread in your posts, you are not doing so
and that makes it very hard to follow a thread.

You do what I said, monitor for Explorer and Inspector Close. See the VB 6
COM addin template ItemsCB on the Resources page at www.microeye.com for one
example of ways to do that. Also see
http://www.microeye.com/resources/res_outlookvsnet.htm for .NET COM addin
information.

However, whatever you do will have problems unless you explicitly release
all your objects and if using .NET code explicitly call to release your COM
objects and then you might also have to explicitly call the garbage
collector.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top