There are 3 parts to this question:
1. What is the best way to create a new version of a COM (Component
Object Model) dll (called e.g. MyCOMDll.dll version 1.0) where several
interfaces (called e.g. IMyInterfaceA, IMyInterfaceB, IMyInterfaceC)
and respective coclasses implementing them have changed? I know that
COM interfaces may not be changed once published, and therefore I
should create new interfaces with the changes IMyInterfaceA2,
IMyInterfaceB2, IMyInterfaceC2. What I need help on is whether it is
generally better a) to put these new interfaces and associated
implementing coclasses into a replacement compilation of the existing
dll (thus creating MyCOMDll.dll version 2.0, which contains not only
the new interfaces and coclasses but the old ones as well, thus
preserving backward compatibility in this way), or b) to put the new
interfaces and associated coclasses into a brand new dll (called e.g.
MyCOMDll2.dll version 1.0), with backward compatibility being
available to clients if they keep a copy of the old dll on their pc?
Method a) produces ever larger dll file sizes, but avoids possible
confusion of clients between the different dlls.
2. I also presume that if solution b) is adopted (ie a brand new dll),
if a fourth interface defined in the old dll, IMyInterfaceD, has NOT
changed, then it is OK to put identical code for IMyInterfaceD and its
associated coclass code into the new dll, either with the same uuids
(Globally Unique Identifiers) as before, or with the brand new ones
that would be typically generated by ATL (Microsoft Visual c++ 6.0) or
Microsoft Visual Basic 6.0, but which is better, or does it not
matter? I've noticed (using the Visual Studio 6 OLE/Object Viewer)
that Microsoft have maintained the same uuids for many interfaces in
DAO version 3.6 dll as in DAO version 3.51, so this points in the
direction of keeping the same uuids, but this requires some extra work
( overwriting by hand the new uuids which are created in the .idl and
.rgs files by Visual Studio using Insert, New ATL Object, Simple
Object [I'm talking here about an ATL COM App Wizard project in Visual
C++), and how would one alter the uuids generated behind the scenes by
Visual Basic in a VB Active X dll?
3. Again, if solution b) is adopted, under some circumstances, I may
wish to prevent a client (e.g. in an Excel VBA project) from adding a
reference to BOTH dlls. I notice that Microsoft prevent one from
setting a reference to both DAO 3.51 and DAO 3.6 - how is this done,
and when is this a good idea?
The point of these related questions is that we are producing new
versions of software, and want to enable clients to keep backwards
compatibility whilst minimising any problems from future
disruption/confusion/ever increasing file sizes. (I realise that there
will be some tradeoff between these somewhat conflicting objectives,
but would like to know what generally accepted best practice is). |
Clarification of Question by
plucktick-ga
on
04 Dec 2003 19:49 PST
I'm assuming that someone with experience of creating new versions of
COM dlls at Microsoft (or other large software house) will be able to
answer this question in a few paragraphs (with any relevant links),
I'm not expecting a large treatise, just the key points about best
practice from those who have already been down this route.
|
Clarification of Question by
plucktick-ga
on
04 Dec 2003 19:52 PST
I should also mention that I would like an answer as soon as possible
(I can't see how to alter the default 1 month expiry time), and would
be prepared to add a tip for an answer before 8 December.
|
Clarification of Question by
plucktick-ga
on
05 Dec 2003 04:48 PST
I now know part of the answer to 3 - dlls which are referenced must
have unique library names, so to prevent both MyCOMDll and MyCOMDll2
from being referenced, all one needs to do is give their libraries the
same name (e.g. MYLIBRARY). For c++, this needs to be done by hand in
the idl file for MyCOMDLL2 and references to LIBID_... in the coclass
.h files need to be changed to LIBID_MYLIBRARYLib. For VB the library
name is taken from the Project Name, so this needs to be set to
MYLIBRARY.
However, I still need to know under what circumstances this is a good idea.
|
Request for Question Clarification by
mathtalk-ga
on
06 Dec 2003 07:01 PST
Hi, plucktick-ga:
Perhaps one approach to answering the question is to review
Microsoft's own experiences with various ways of "versioning" COM
interfaces, which experience has certainly motivated some aspects of
the .Net rearchitecting of component runtime support.
A good illustration, in my opinion, is the history of Microsoft XML
parsers, provided as COM DLLs. Between versions 2 and 3 (they are now
on version 4) Microsoft "experimented" with something they called
optional side-by-side installation. The details are interesting
mainly to developers, but with version 4 they abandoned this support.
Basically when a COM component is requested, the Windows registry is
needed to resolve what DLL or EXE will service the request.
Components can be requested in various ways, and in some of these a
version can be specified. In general though the registry will point
requests to the most recent version of coclasses and their interfaces.
regards, mathtalk-ga
|
Clarification of Question by
plucktick-ga
on
07 Dec 2003 04:07 PST
Hi mathtalk-ga, and thanks for the comments re XML and the registry
which are interesting. However, I'm not sure whether you are asking
for clarification or not in your comments? What further
information/clarification do you need to provide an answer? One
clarification I can add is that at the moment, I am only interested in
COM dlls (as in the question title), rather than exes, if that helps.
Regards
|
Clarification of Question by
plucktick-ga
on
07 Dec 2003 04:12 PST
I have just increased the price for the question from $25 to $50, in
the hope of getting an answer soon.
|
Clarification of Question by
plucktick-ga
on
15 Dec 2003 09:08 PST
hi Mathtalk-ga, and thanks - your comment does indeed help to clarify
matters. I do have a copy of Don Box's book and have been referring to
it, but it doesn't seem to address the details of my question.
However, from experiments that I have done, and from examining the
type libraries of the MSXML dlls (as you suggested) plus your other
comments, I think I have made some progress.
I think I will be able to accept what you have given me so far as
useful enough to qualify as an answer if you wouldn't mind clarifying
the following points which arise:
- you say that a replacement dll is best in general, but which of my
two options a) and b) do you mean? A "replacement dll" could be
either: a new version number of a dll with the same name
(MyCOMdll.dll, which will overwrite the old version on clients'
machines), or a dll with a new name, MYCOMDll2.dll. I appreciate that
backwards compatibility can be maintained in both cases respectively
by (a) implement the old interfaces in the new dll, and b) either
ignore the old interfaces [clients can use the old dll], or implement
them in the new dll
- I have carried out experiments with altering a new solution (of type
b) MyCOMDll2.dll by editing the IIDs, CLSIDs and LIBID by hand to
retain their values in the previous version. Two problems I noticed
were: (1) c++ client code creating objects of a legacy coclass will
get the implementation from the most recently registered dll, even if
this happens to be the older version! I.e. if version MyCOMDll.dll
and MyCOMDll2.dll both include code (with the same LIBID and CLSID)
for MyClass, ordinarily MyCOMDll2.dll (the most recent version) will
have be the most recently registered dll, but if the user reregisters
MyCOMDll.dll (the older version) via browsing to it from VBA's Tools,
References window, then c++ client code will get MyCOMDll.dll's
implementation! This is only a problem for c++ client code, since
VBA/VB code has to explicitly set a reference to the desired dll. (2)
If MyCOMDll2.dll has a different LIBID, but the same CLSIDs for legacy
coclasses, which dll's implementation will a c++ client get? (Perhaps
again the most recently registered dll? I haven't had time to test
this)
- How can one tell from the Registry which is the most recently
registered dll out of 2 or more dlls with the same LIBID? (This is
important for the point above)
- How can one tell from the Registry what the library short name for a
dll is? This is the name which appears in an ATL COM project's idl
file immediately after the Library statement, and it is also used by
VB/VBA to display library short names in the Object Browser.
I appreciate your time, and will increase the fee to reflect the fact
that some additional research may be needed to answer the above
clarification requests. I also appreciate that there are often no
definite answers to the points I raise, but I am finding your comments
useful, so please do persevere - I think we are very close to answer!
Regards, plucktick-ga
|