简体   繁体   English

我如何告诉vb6每次创建dll时都不要创建新版本的interfaces / com对象?

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

I have vb6 com server (ActiveX DLL project) that is used by .NET code 我有.NET代码使用的vb6 com服务器(ActiveX DLL项目)

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. 每次我将更改放入vb6代码并生成dll时,我也必须重新编译我的.NET客户端代码,因为它看起来像VB6为接口和com对象生成新的GUID或版本。

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. 我承认这是一个很好的做法,因为进行了更改,但我想禁用此行为,以便每次更新我的vb6 dll时都让我的.NET客户端代码相同。

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? 无论对COM对象或COM接口做了哪些更改,我如何告诉VB6保持ActiveX dll的所有GUID和版本都一样?

The selection in the Project + Properties, Components tab matters. Project + Properties,Components选项卡中的选择很重要。 You have to select "Binary compatibility" here to force it to re-use old guids. 您必须在此处选择“二进制兼容性”以强制它重复使用旧的guid。 And keep a copy of the DLL around to act as the "master" that provides the guids, check it into source control. 并保留DLL的副本作为提供guid的“主”,将其检入源代码控制。

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. 当您添加新类时,您还必须更新该副本,以便将来的版本知道为这些添加的类重用相同的guid。 Easy to forget, pretty hard to diagnose when you do. 容易忘记,很难诊断。

It is very dangerous, reusing guids is a very strong DLL Hell inducer. 这是非常危险的,重用guids是一个非常强大的DLL Hell诱导器。 You can get old client programs to continue using the new DLL as long as you careful avoid changing existing methods. 只要您小心避免更改现有方法,就可以使旧的客户端程序继续使用新的DLL。 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. 遇到旧版DLL的更新客户端将以非常恶劣的方式失败,访问冲突崩溃几乎无法诊断。

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. 看一些人的VB6库并看到高达数百的接口版本号(GUID和版本号都用于识别接口)可能会很吓人,即使他们认为他们已经仔细管理二进制兼容性。

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. 新的要求甚至错误修复可能需要对一个程序的库接口进行重大更改,而不是其他12个或20个程序。

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. 您必须通过显式手动版本控制来适应这一点,您实际上更改了库的名称以反映具有全新GUID集的新版本。 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. 通常这是通过编号完成的,因此像“FuddInvLib1.DalRoot”这样的ProgId可以与两个具有完全不同的GUID集的库中的新“FuddInvLib2.DalRoot”并存:FuddInvLib1.dll和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. 由于每个都是为了支持目的而更改,您可以随着时间的推移每个版本中保持二进制兼容版本,最终完全淘汰FuddInvLib1.dll。 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. 这当然意味着随着时间的推移迁移客户端代码以使用更新的库或库,但您可以按计划的速度逐步增加。

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. COM合同规定接口定义是不可变的(不改变方法名称,参数列表,方法顺序,方法数量),但这些实现可以自由改变。 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). (VB二进制兼容性不会允许您更改的方法签名或方法才能在一个接口,但它可以让你以新的方法追加到它-去图)。 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. 尽管如此,对于生产中的DLL的接口或其方法进行任何更改都是“最糟糕的做法”,因为多年的DLL Hell已经证实并且正如Hans所解释的那样。

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. 通过版本更改保留二进制兼容性的一种方法是向组件添加新接口,并且在生产任何版本的DLL后永远(永远不会)触摸旧接口。 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. 使用旧接口错误的新客户端可以使用iUnknown.QueryInterface方法捕获。 In VB, you can do this: 在VB中,您可以这样做:

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. 这将调用QueryInterface方法,如果引用旧版本的DLL,则返回false。 You can message the user that he needs to install the newer version of the DLL and quit. 您可以通知用户他需要安装较新版本的DLL并退出。 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; 如果不支持新接口,则您拥有旧版本的DLL; you can message the user to install the newer version and go from there. 您可以通知用户安装较新版本并从那里开始。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用清单在vb6库项目中引用Com可见的C#dll? - How can I reference a com visible C# dll in a vb6 library project using a manifest? 一个简单的C#DLL - 如何从Excel,Access,VBA,VB6中调用它? - A Simple C# DLL - how do I call it from Excel, Access, VBA, VB6? 如何将数组(通过引用,在VB6中)传递给C \\ C ++ * .dll子例程? - How do I pass an Array (By Reference, in VB6) to a C\C++ *.dll subroutine? 如何从C#客户端连接到VB6 Com +服务器 - How do I connect from a C# client to a VB6 Com+ server 当它具有ref参数时,如何从带有动态参数的C#中调用VB6 COM对象? - How do I call a VB6 COM object from C# with dynamic when it has a ref parameter? 如何将.NET COM dll中的结构或类返回给消耗的VB6应用程序? - How do you return an struct or class from a .NET COM dll to a consuming VB6 application? 你如何在 vb6 中将 C# COM interropt DLL 作为参数传递 - how do you pass a C# COM interropt DLL as param in vb6 如何在VB6中注册不用作COM互操作的.NET DLL? - how to register a .net dll not being used as a com interop in vb6? 如何将对象集合从VB6传递到.NET? - How can I pass a collection of objects from VB6 to .NET? 如何将结构从C#发送到VB6,以及从​​VB6发送到C#? - How do I send a struct from C# to VB6, and from VB6 to C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM