IDTExtensibility2_OnDisconnection does not fire, Outlook.exe hangi

B

Bert_Bert

Hi,
I try to develop Outlook addin in VB6.

I successfully compile DLL library, the addin adds Button to a toolbar. It
reads some items from a folder using Redemption session.

I want to unload and free memory correctly but, honestly I do not know how.
I expect OnDisconnection event should occur "when the COM add-in is
disconnected." but this happens when ?

I want as farr as I close Outlook that my addin also frees up all the
objects used and logs off the rdo session. I have the freeing code in this
procedure, set breakpoint, but it never gets fired and Outlook.exe hangs in
TaskManager when I try to close it (2003, SP3, EN). Even after I kill
Outlook.exe process, it does not fire the event so I cannot clean my objects
and still dont know whether they are stuck in memory or not.

Any hint welcome
thank you
 
K

Ken Slovak - [MVP - Outlook]

That's the famous OnDisconnection bug, it affects all COM addins for Outlook
2000 - 2003. The bug was fixed in Outlook 2007.

OnDisconnection won't fire as long as any Outlook objects are still
instantiated. So as a workaround you have to handle the Explorer.Close() and
Inspector.Close() events of the Explorers and Inspectors collections. In
those events you test for Explorers.Count and Inspectors.Count.

The following snippets assume that _Explorers is the Explorers collection
and _Inspectors is the Inspectors collection.

in Explorer.Close():

If ((_Explorers.Count <= 1) And (_Inspectors.Count = 0)) Then
'release all Outlook objects so OnDisconnection will fire
End If

in Inspector.Close():

If ((_Explorers.Count = 0) And (_Inspectors.Count <= 1)) Then
'release all Outlook objects so OnDisconnection will fire
End If
 
B

Bert_Bert

Ken,
I am a bit confused how can I catch Close event from all instances of
Explorers and inspectors.

I came across your snippet here:
http://www.tech-archive.net/Archive...e.developer.com.add_ins/2005-11/msg00045.html

there you remember in _NewExplorer just the newly added "active" one
declared with withevents.

If I want to be systematic, I would have to rememeber each and every
Explorer user ever opened and watch for it's Close event.

However I cannot declare
Private Withevents my_array() as Outlook.Explorer
it does not allow me to declare array as withevents.

It is not clear then what happens when I once declare a variable withevents
an thed add it into array via Set. Then as soon as I Set another instance
(or perhaps set it to Nothing, or perhaps the temp variable gets out of the
scope), old Events watching mechanism gets deactivated, so I can watch just
the last opened explorer, never the first ones.

Please, could you push me the right way ?

You work with "ActiveExplorer" only, but what if user closes "inactive" one,
actuially, is it trechnically possible to do it ?
 
K

Ken Slovak - [MVP - Outlook]

If you want to handle more than one possible open Explorer or Inspector what
you do is in the New* event (NewExplorer or NewInspector) you decide if you
want to handle that Explorer/Inspector. If so you instantiate an instance of
a class that declares the Explorer or Inspector objects WithEvents and then
handle any event for that object in the class. So there you'd be handling
the Close events. The class is then added to a collection of some sort to
keep the class instances alive.

When the main class's Inspector.Close or Explorer.Close events fire you can
check for the count there and terminate if you want.

I have sample VB6 code that does that sort of thing as a COM addin template
on my Web site. The code is specifically for Outlook 2007, but it shows the
principles of wrapper classes, etc. for any version of Outlook. You could
download that and change the references to Outlook 2003 to review the code.
There is specific Outlook 2007 code there so it wouldn't compile under
Outlook 2003 but it would allow you to see what's going on. The download for
that sample is on http://www.slovaktech.com/outlook_2007_templates.htm
 
B

Bert_Bert

you do is in the New* event (NewExplorer or NewInspector) you decide if you
want to handle that Explorer/Inspector. If so you instantiate an instance of
a class that declares the Explorer or Inspector objects WithEvents and then

well, actually I thought a lot about it and finally managed to do it exactly
as you write - instantiating a particular withevents variable within a
wrapper class
Then whenever I hold new Exp, I instantiate wrapperExp, store the Exp in my
internal withevents value and perform maintenance task of adding my wrapper
to array.

this was the only workaround I was able to imagine and it seems now for
Explorers to work :)

I had to workout my own mechanism of new exp and isp management as they are
added and removed, but I would never say it is such an amount of code to
write and debug

Kne, thank you
 

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