patterncsharpMinor
Shared VB6 *and* VBA extensibility add-in with OnConnect and OnDisconnect handling
Viewed 0 times
handlingsharedwithvb6ondisconnectextensibilityvbaandaddonconnect
Problem
Rubberduck works well enough when the VBE is of the VBA variety, but it currently only works when the Rubberduck is configured to load at VBA start-up, and it has a tendency to crash the host application or fail to shutdown when exiting. There's a number of outstanding issues around being able to load Rubberduck after the IDE is already loaded, and to unload Rubberduck without closing the IDE.
There's also a number of requests for adding the ability to work with VB5/VB6. While VB and VBA both have VBIDE libraries that are very similar, and they both support the
I've relied heavily on the MZ Tools documentation of Carlos Quintero of MZ-Tools, and the Microsoft documentation in coming up with a bare-bones solution that attempts to:
I've created my own interop assemblies for the respective VBEs:
Connect.cs
```
using Extensibility;
using Fubaa.Interop.VB6Ext;
using Fubaa.Interop.VBA6Ext;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyAddin
{
[ComVisible(true)]
[Guid(ClassId)]
[ProgId(ProgId)]
public class Connect : IDTExtensibility2
{
private const string ClassId = "506EC676-068F-497D-BEBB-B8EE42A34573";
private const string ProgId = "MyAddin.Connect";
private IVBE _vbe;
private object _Addin;
private bool isLoaded;
public void OnAddInsUpdate(ref Array custom)
{
Debug.WriteLine("Begin Event: OnAddInsUpdate");
Debug.WriteLine(" Addin is Loaded:" + isLoaded.ToString());
Debug.WriteLine("End Event: OnAddInsUpdate"
There's also a number of requests for adding the ability to work with VB5/VB6. While VB and VBA both have VBIDE libraries that are very similar, and they both support the
IDTExtensibility2 interface, they are not interchangeable.I've relied heavily on the MZ Tools documentation of Carlos Quintero of MZ-Tools, and the Microsoft documentation in coming up with a bare-bones solution that attempts to:
- Allow for the add-in to be loaded/unloaded as the user requires.
- Allow for the add-in to work under VB5/VB6 and 32/64-bit VBA.
I've created my own interop assemblies for the respective VBEs:
- VB6's VBIDE -
Fubaa.Interop.VB6Ext
- VBA's VBIDE -
Fubaa.Interop.VBA6Ext
Connect.cs
```
using Extensibility;
using Fubaa.Interop.VB6Ext;
using Fubaa.Interop.VBA6Ext;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyAddin
{
[ComVisible(true)]
[Guid(ClassId)]
[ProgId(ProgId)]
public class Connect : IDTExtensibility2
{
private const string ClassId = "506EC676-068F-497D-BEBB-B8EE42A34573";
private const string ProgId = "MyAddin.Connect";
private IVBE _vbe;
private object _Addin;
private bool isLoaded;
public void OnAddInsUpdate(ref Array custom)
{
Debug.WriteLine("Begin Event: OnAddInsUpdate");
Debug.WriteLine(" Addin is Loaded:" + isLoaded.ToString());
Debug.WriteLine("End Event: OnAddInsUpdate"
Solution
OnConnection and OnStartupComplete
I can forsee a problem arising. Assume the addin is started with
at the top of the
While we are at
I can forsee a problem arising. Assume the addin is started with
ext_ConnectMode.ext_cm_AfterStartup then in the OnConnection() handler you are calling DoInit(). Afterwards the OnStartComplete() handler will be called and you call DoInt() again no matter if it had been called already. You should have at leastif (isLoaded) { return; }at the top of the
OnStartComplete() handler.While we are at
OnConnection´...
- methdod parameter should be named using
camelCase casing.
- swallowing an exception is bad style unless you have a very good reason for it. If you have a very good reason you should state this reasing as a comment so future developers know why you did what you did. In addition in your code if an exception is thrown the default flow just continues and you could see a
Addin is Loaded:True but that wouldn't be the truth.
- if
Application is neither Fubaa.Interop.VBA6Ext.VBE nor Fubaa.Interop.VB6Ext.VBE you should return from the handler.
DoInit() and DoCleanup()
Why are these methods public ? Make them private because thats the only scope they need.
Am I crazy to use an IVBE interface, or should I just use dynamic?
IMO the interface is good as it is. You have implemented it easy and it serves its purpose.
Using dynamics` instead can lead to compilable code which will throw at runtime. IMO its better to have compiler type checking.Code Snippets
if (isLoaded) { return; }Context
StackExchange Code Review Q#136796, answer score: 4
Revisions (0)
No revisions yet.