COM, как известно, делает возможной обратную совместимость при выпуске новых компонентов или приложений. Это возможно, потому что интерфейсы в COM стабильны, то есть они не меняются.
Я изо всех сил пытался найти справочник или книгу, в которой рассказывалось бы о том, как эволюционировать COM-интерфейс от версии к версии.
Ниже приведены мои требования:
У нас есть приложение, которым можно управлять с помощью автоматизации ole. Новые версии этого приложения могут быть установлены параллельно с более старыми версиями.
COM-клиенты этих приложений могут использовать независимый от версии PROGID; в этом случае они работают с самой последней версией приложения или зависящий от версии PROGID; в этом случае они работают с конкретной версией приложения.
Изменения в автоматизации COM не должны сломать ни одного из клиентов.
Давайте рассмотрим пример:
#include <olectl.h>
#include <fxbase\autoif.h>
[
uuid(A1B3A66F-806F-46a2-82D9-9C278F415148),
lcid(-1),
version(1.0)
]
library LIB
{
importlib("stdole2.tlb");
[
uuid(82CDE055-790A-4505-BF3E-3282170C8FC6),
helpstring("Document"),
oleautomation,
dual,
nonextensible
]
interface IDocument : IDispatch
{
[id(0x00000001), propget, helpcontext(0x0012c94a)]
HRESULT Name([out, retval] BSTR* psName);
[id(0x00000001), propput, helpcontext(0x0012c94a)]
HRESULT Name([in] BSTR psName);
}
[
uuid(919B9E6E-76C0-4c23-A188-5840E5900997),
helpstring("Application object."),
oleautomation,
dual,
nonextensible
]
interface IApplication : IDispatch
{
[id(0x00000001), propget, helpstring("Returns the active document of the application.")]
HRESULT ActiveDocument([out, retval] IDocument** retval);
}
[
uuid(E0AA6FCA-AEF1-460b-A1F9-26250C28594B),
helpstring("Application 1.0 Class"),
appobject
]
coclass Application
{
[default] interface IApplication;
interface IDispatch;
}
}
Допустим, я хочу опубликовать версию 2.0 этого приложения, которая расширяет некоторые интерфейсы. Вот мой наивный подход к версии 2.0:
#include <olectl.h>
#include <fxbase\autoif.h>
[
uuid(3D4688A2-91F8-4cd8-989A-845810A05557),
lcid(-1),
version(2.0)
]
library LIB
{
importlib("stdole2.tlb");
[
uuid(82CDE055-790A-4505-BF3E-3282170C8FC6),
helpstring("Document"),
oleautomation,
dual
]
interface IDocument10 : IDispatch
{
[id(0x00000001), propget, helpcontext(0x0012c94a)]
HRESULT Name([out, retval] BSTR* psName);
[id(0x00000001), propput, helpcontext(0x0012c94a)]
HRESULT Name([in] BSTR psName);
}
[
uuid(AF404510-216A-407e-99F4-0636AF071B68),
helpstring("Document"),
oleautomation,
dual,
nonextensible
]
interface IDocument : IDocument10
{
[id(0x00000001), propget, helpcontext(0x0012c94a)]
HRESULT Type([out, retval] BSTR* psType);
[id(0x00000001), propput, helpcontext(0x0012c94a)]
HRESULT Type([in] BSTR psType);
}
[
uuid(919B9E6E-76C0-4c23-A188-5840E5900997),
helpstring("Application object."),
oleautomation,
dual
]
interface IApplication10 : IDispatch
{
[id(0x00000001), propget, helpstring("Returns the active document of the application.")]
HRESULT ActiveDocument([out, retval] IDocument** retval);
}
[
uuid(6A851C3F-21DF-4f5e-A4D6-2EF5A9D234C6),
helpstring("Application object."),
oleautomation,
dual,
nonextensible
]
interface IApplication : IApplication10
{
[id(0x00000002), propget, helpstring("Is the application visible.")]
HRESULT Visible([out, retval] BOOL* retval);
}
[
uuid(AA760349-1682-4ab6-BF0C-C02E620715CF),
helpstring("Application 2.0 Class"),
appobject
]
coclass Application
{
[default] interface IApplication;
interface IDispatch;
}
}
Это правильный способ сделать это?
Должен ли я добавить класс Application10 и Application20 в реестр, чтобы добавить возможность создания разных версий приложения для клиентов сценариев?
Правильно ли менять версию и GUID библиотеки типов?
IDocument в версии 2.0 имеет новый IID. Могу ли я по-прежнему использовать IDocument в IApplication.ActiveDocument?
Как мне зарегистрировать coclass или интерфейс в реестре Windows в разных версиях?
Обратите внимание, что я не использую ATL или другие библиотеки, кроме WIN32-API.
Если вы знаете, где я могу найти информацию об этом (книги, справочные материалы и т. Д.), Пожалуйста, предложите один.
Буду очень признателен за вашу помощь.