Fog Creek Software
Discussion Board




Advice on pluggable app

Hi -

I'm hoping someone can point me to a site or two on how to write an app that supports plug-ins in VB6.  I'd like to have the app discover the plug-in at runtime (so I don't have to do a rebuild every time I (or someone else) creates a new one), and I realize that it's going to require clearly defined interfaces before hitting version 1.0.

Essentially I'd like to be able to access similar data that's been written in a variety of formats, each of which will require a different parser/generator to read/write, but they all share similar logic behind the scenes.  I want the overall app to deal with an abstraction of the data and feed that into the plugins to write the data.

(and please, I'd rather keep to VB6 unless there is a really compelling reason not to.  If there is, please state it clearly.  I'm confident it can be done in VB6.)

So...any ideas?  Thanks in advance.

Aaron F Stanton
Monday, March 01, 2004

Delphi syntax is very close to VB so I am responding with the new 'Hydra' product, which is darn convenient for pluggable apps: http://www.remobjects.com  The authors are VB/Delphi/C# gurus so you'd probably get some decent VB-to-Delphi conversion support on their NGs.  They plan a .Net version in Q3 so VB.Net would be another option for Hydra at that time.

Joe Hendricks
Monday, March 01, 2004

For clarification, do you mean that you're writting an app in VB6 and you want it to support plug-ins, or that you're writting an app and you want it to accept plug-ins which are themselves written in VB6?

Either way, have a look at the IDTExtensibility2 interface.  This is the interface that all Microsoft Office applications, as well as Visual Studio, use to host add-ins.  Since it's a COM interface, the add-in can be implemented in just about any language.  (You users could use VB6 to create add-ins, but wouldn't be limited to it.)

You could define your own interface instead, but since IDTExtensibility2 is pretty well known and used, there would be less of a learning curve for your users.  E.g., Visual Studio .Net has a wizard to help create add-ins that implement IDTExtensibility2.

Robert Jacobson
Monday, March 01, 2004

Since you're working in VB6, you're dealing with COM plug-ins. You'll need to define at least two interfaces:

1) An interface the plug-in object implements that the host can call.

2) An interface the host implements that the plug-in can call.

Although you've described a scenario where the plug-in is just processing fired off by the host, so you may not need #2.

I would strongly, STRONGLY urge you to define your interfaces in IDL rather than in VB. You'll get much fewer problems in the short/medium run.

As far as finding plug-ins are concerned, you've got a couple of options. One is to use the COM Component Category manager. Define a category for "My app's plug-ins", and then the plug-ins register as members of that category. I have no idea how to deal with the category manager from VB, though.

Another option would be to define a standard registry key that the plug-ins could write something into at install time. Then the app would just walk through that key and create whatever was listed.

Chris Tavares
Monday, March 01, 2004

> I'd rather keep to VB6 unless there is a really compelling reason not to.  If there is, please state it clearly.  I'm confident it can be done in VB6.

This doesn't quite qualify as a "really compelling" reason, but just for the record, .NET is really good at dynamically loaded stuff.  However that would require you to convert to VB.NET, which is presumably what you're trying to avoid :-)

John Rusk
Monday, March 01, 2004

Hi -

I'll take these one at a time in the order of appearance so far:

I looked at Hydra, and it does look interesting.  If I had Delphi, I'd probably use it, but I don't.  I have Visual Studio 6 Enterprise.

I'm planning on writing an app in VB6 that uses plugins.  Since the interfaces will be clearly defined for COM, any language that can deal with COM should be able to create plugins for it - whether it be VB6, VC++, or even a .Net language via interop.

As far as definining interfaces in IDL rather than VB6, I do suppose that as long as I follow the base rules (return HRESULTs, use mostly standard types, etc.) it would make them easy to use in VB6, but would it make sense to at least hash them out in VB6 and extract the IDL from the typelib and then work with that?  Also, I'm unfamiliar with the Component Manager - I should read up on that.  Registry keys had occurred to me, but it would also be nice to have the plugin install be a simple "copy the file into the plugin directory" and then let the app search the directory for dll's.  Would that work?

Lastly, I do know .Net is good at dynamically loading assemblies.  Heck, you can dynamically *create* assemblies at runtime and use them on a whim.  You are correct that I am trying to avoid converting to .Net.  I can't afford the static linkers I see out there, I question whether or not they violate the redistribution license of .Net, and I don't feel a need to have my users download a 22 meg runtime.  As Joel concluded elsewhere, I will wait until it is pervasive.

Thanks for your comments, all.  I look forward to reading some more.

Aaron F Stanton
Monday, March 01, 2004

Re: Using IDL instead of VB.

The reason I recommend using IDL instead of VB is that VB plays fast and loose with the COM rules. GUIDs change on a dime, and implementing a COM interface in C++ that's defined in VB is a real nightmare (I speak from personal experience).

Another option would definately be to hash it out in VB, pull the IDL out of the TLB, and tweak and recompile it. Some weirdness always seems to end up in the TLB when you do this though, so be prepared.

Of course, I'm a C++/ATL guy, so IDL isn't an issue for me.

As far as scanning a directory to find plug-ins goes, here's the problem: COM objects aren't loaded by filename, they're loaded by type (CLSID). So you may just dump files into a directory, but you don't have the file->clsid mapping you need to call CreateObject. Thus the registry key. And if you're using the registry anyway, why bother forcing everything into a single directory?

Chris Tavares
Tuesday, March 02, 2004

Hi -

I've never tried to implement C++ COM objects that were originally defined in VB, so I have to accept that it's a pain.

I am glad that the extraction of IDL and then tweaking it is a viable option.  It tells me that I have at least a bit of understanding here.  What sorts of weirdness tends to show up?  Would that be a serious impediment to what I'm trying to accomplish?

I hadn't considered that if I'm using the registry anyway it doesn't really matter where the plugins go.  I was just thinking that for convenience there would be a common directory, but it's not essential.  (I suppose that my idea was that if someone else wanted to write a plugin, it would be easy for them to just drop it into the directory and not have to futz with registering/unregistering it.)

Maybe plugins isn't exactly the term I'm wanting - it's more like installable file filters, but the pluggable nature is really what I'm after.  I do suppose that plugin architecture is appropriate in that I also want the system itself to be extensible, but that's a bit secondary to the file I/O.

Again, thanks!

Aaron F Stanton
Tuesday, March 02, 2004

*  Recent Topics

*  Fog Creek Home