I have rephrased this question.
When .net objects are exposed to COM Clients through COM iterop, a CCW (COM Callable Wrapper) is created, this sits between the COM Client and the Managed .net object.
In the COM world, objects keep a count of the number of references that other objects have to it. Objects are deleted/freed/collected when that reference count goes to Zero. This means that COM Object termination is deterministic (we use Using/IDispose in .net for deterministic termination, object finalizers are non deterministic).
Each CCW is a COM object, and it is reference counted like any other COM object. When the CCW dies (reference count goes to Zero) the GC won't be able to find the CLR object the CCW wrapped, and the CLR object is eligible for collection. Happy days, all is well with the world.
What I would like to do is catch when the CCW dies (i.e. when its reference count goes to zero), and somehow signal this to the CLR object (e.g. By calling a Dispose method on the managed object).
So, is it possible to know when the reference count of a COM Callable Wrapper for a CLR class goes to Zero?
and/or
Is it possible to provide my implementation of AddRef & ReleaseRef for CCWs in .net?
If not the alternative is to implement these DLLs in ATL (I don't need any help with ATL, thanks). It wouldn't be rocket science but I'm reluctant to do it as I'm the only developer in-house with any real world C++, or any ATL.
Background
I'm re-writing some old VB6 ActiveX DLLs in .net (C# to be exact, but this is more a .net / COM interop problem rather than a C# problem). Some of the old VB6 objects depend on reference counting to carry out actions when the object terminates (see explaination of reference counting above). These DLL's don't contain important business logic, they are utilities and helper functions that we provide to clients that integrate with us using VBScript.
What I'm not trying to do
- Reference count .net objects instead of the using the Garbage Collector. I'm quite happy with the GC, my problem isn't with the GC.
- Use object finalizers. Finalizers are non deterministic, in this instance I need deterministic termination (like the Using/IDispose idiom in .net)
- Implement IUnknown in unmanaged C++
If I've to go the C++ route I'll use ATL, thanks. - Solve this using Vb6, or re-using the VB6 objects. The entire point of this exercise is to remove our build dependence on Vb6.
Thanks
BW
The Accepted Answer
Folks a thousand thanks to Steve Steiner, who came up with the only (possibly workable) .net based answer, and Earwicker, who came up with a very simple ATL solution.
However the accepted answer goes to Bigtoe, who suggests wrapping the .net objects in VbScript objects (which I hadn't considered to be honest), effectively providing a simple VbScript solution to a VbScript problem.
Thanks to all.