gpt4 book ai didi

com - 如何进化一个 COM 接口(interface)?

转载 作者:行者123 更新时间:2023-12-04 07:14:14 25 4
gpt4 key购买 nike

众所周知,COM 可以在发布新组件或应用程序时实现向后兼容。这是可能的,因为 COM 中的接口(interface)是稳定的,即它们不会改变。

我努力寻找有关如何从一个版本升级到另一个版本的 COM 接口(interface)的描述的引用资料或书籍。

以下是我的要求:

我们有一个可以由 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 版,它扩展了一些接口(interface)。这是我对 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 是否正确?

2.0 版中的 IDocument 有一个新的 IID。我还能在 IApplication.ActiveDocument 中使用 IDocument 吗?

我应该如何在不同版本的 Windows 注册表中注册 coclass 或接口(interface)?

请注意,我不使用 ATL 或除 WIN32-API 之外的其他库。

如果你知道我在哪里可以找到这方面的信息(书籍、引用资料等),请推荐一个。

我将衷心感谢您的帮助。

最佳答案

是的,您需要更改 class id如果希望多个版本共存,您的对象。但是,您可以维护与版本无关的 program idredirects to the class id of the current version 的“Word.Application”或“InternetExplorer.Application” .向后兼容性很难维护。 MSXML 显然放弃了与版本无关的 progID 的做法。

如果您决定保留旧接口(interface)(推荐),则需要在新对象中同时实现新接口(interface)和旧接口(interface)。

您可能需要检查 Microsoft Office 的注册表项。它很好地保持了向后兼容性。

新接口(interface)的建议名称为接口(interface)名称加上版本号,例如 IHtmlDocument6 .

关于com - 如何进化一个 COM 接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1620933/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com