How do I tell vb6 not to create new versions of interfaces/com objects everytime I make dll?

核能气质少年 提交于 2019-12-23 12:11:17

问题


I have vb6 com server (ActiveX DLL project) that is used by .NET code

Everytime I put changes into vb6 code and make dll, I have to recompile my .NET client code as well, because it looks like VB6 generates new GUIDs or versions to interfaces and com-objects.

I admit it's a good practice because changes are made but I'd like to disable this behavior to let my .NET client code be the same everytime I update my vb6 dll.

How can I tell VB6 to keep all GUIDs and versions for ActiveX dll the same no matter what changes are done to COM objects or COM interfaces?


回答1:


The selection in the Project + Properties, Components tab matters. You have to select "Binary compatibility" here to force it to re-use old guids. And keep a copy of the DLL around to act as the "master" that provides the guids, check it into source control.

When you add new classes then you also have to update that copy so future versions will know to reuse the same guids for those added classes. Easy to forget, pretty hard to diagnose when you do.

It is very dangerous, reusing guids is a very strong DLL Hell inducer. You can get old client programs to continue using the new DLL as long as you careful avoid changing existing methods. Not just their method signature but also their implementation. An updated client that encounters an old version of the DLL will fail in a very nasty way, the access violation crash is near impossible to diagnose.




回答2:


Using Binary Compatibility only buys you so much. Maintaining interface compatibility over the long term only works well for very simple libraries or when your interfaces were very well planned and future-proofed from the beginning. It can be scary to look at some peoples' VB6 libraries and see interface version numbers in the high hundreds (both GUIDs and version numbers are used to identify an interface) even when they think they've carefully managed Binary Compatibility.

It can get even worse when you have a system of programs that share libraries. A new requirement or even a bug fix might require a breaking change to a library's interface for one program but not the other 12 or 20 of them.

You have to accomodate this by explicit manual versioning, where you actually change the name of the library to reflect a new version with an entirely new set of GUIDs. Often this is done with numbering, so that a ProgId like "FuddInvLib1.DalRoot" can coexist side by side with a new "FuddInvLib2.DalRoot" in two libraries with entirely different sets of GUIDs: FuddInvLib1.dll and FuddInvLib2.dll.

As each is changed for support purposes you can maintain Binary Compatible versioning within each of them over time, eventually phasing out the FuddInvLib1.dll entirely. This of course means migrating client code to use the newer library or libraries over time, but you have the luxury of doing this incrementally at a planned pace.




回答3:


The COM contract stipulates that interface definitions are immutable (no change to method names, argument lists, order of methods, number of methods), but that implementations can be freely altered. Naive, but true. (VB Binary compatibility will not permit you to change the method signatures or method order in an interface, although it will allow you to append new methods to it--go figure). Nevertheless, making any change to an interface or its methods for a DLL that is in production is "worst practice", as years of DLL Hell have borne out and as Hans has explained.

One approach for preserving binary compatibility through version changes is to add new interfaces to the component, and never (never ever) touch the old interfaces once any version of the DLL is in production. The old client will happily use the old interface, and newer clients can use the new interface.

The new client using an old interface error is trappable by using the iUnknown.QueryInterface method. In VB, you can do this:

If Not TypeOf myObjectReference Is myNewInterface Then
    'gracefully handle the error
End If

This will call the QueryInterface method, and will return false if you are referencing an older version of the DLL. You can message the user that he needs to install the newer version of the DLL and quit. You can wrap this functionality into a function and call it when you initialize the object in your new client. If the new interface isn't supported, you have an old version of the DLL; you can message the user to install the newer version and go from there.



来源:https://stackoverflow.com/questions/24121240/how-do-i-tell-vb6-not-to-create-new-versions-of-interfaces-com-objects-everytime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!