【发布时间】:2015-08-19 08:11:41
【问题描述】:
前提:
我有一个旧的 32 位 COM shell 扩展(用 C++ 编写)。在与较新的 64 位系统多年不兼容之后,我们现在对其进行更新以在 64 位 Windows 环境中工作。
诀窍:
32 位 COM DLL 包含对第三方库的依赖项,没有可用的 64 位版本。因此,我们不能简单地“以 64 位重新编译”。鉴于此限制,我们决定最简单的方法是创建一个“瘦”的 64 位 DLL;本质上是一个空 DLL,仅定义所需的接口,并将所有调用重定向到底层 32 位 COM DLL。
我相信 64 位 COM DLL 和 32 位 COM DLL 之间的这种通信是可能的,通过使用 COM 代理。不幸的是,这似乎是一个非常具体/小众的话题,我一直无法找到很多关于如何从 64 位 COM DLL 调用 32 位 COM API 的资源。
问题:
- 对于启用 32 位 COM DLL 的 64 位功能,这种“瘦 COM 包装器”是否合理?
- 这种方法是否有任何理由不适用于 Windows Shell 扩展?
- 64 位接口定义是否会使用与其 32 位对应物相同的 GUID?
- 这是过去记录的策略吗?
- 是否有任何好的资源可以从 64 位 COM DLL 中调用 32 位 COM API?
说明:
这个问题有许多独特之处,使其与“Using 32-bit shell extensions in Windows 7 64-bit”问题不同。
我不是在问是否可以在 64 位资源管理器进程中加载 32 位 shell 扩展,就像引用的问题那样。相反,我想问是否有可能创建一个瘦 64 位 DLL 实现,它充当 64 位资源管理器进程和 32 位实现之间的桥梁。
明确地说,这是不可能的。
但也许这是?
【问题讨论】:
-
不,你不能。虽然 COM 代理 作为一个概念可以在 x64 客户端和托管在 32 COM 代理中的 32 位进程 COM 服务器之间使用,但 32 位和 64 位的混合并不重要,但对于 Windows Shell 不起作用,它要求所有扩展都与源自操作系统的 Windows 资源管理器进程的“位”相匹配。因此,如果操作系统是 64 位的,那么扩展也必须如此。 – stackoverflow.com/questions/13747836/…
-
在这个特定的提议中,shell 扩展 DLL 的位级别将为 64 位。 在 64 位 DLL 中,然而,具体实现将通过 COM 代理重定向到 32 位 DLL。
-
原始的 32 位 shell 扩展必须托管在某个东西上,可以替代,但它需要模仿我怀疑的 32 位 Windows 资源管理器的所有相关 shell 扩展托管功能,这不是一项简单的任务。与 ActiveX 一样,组件和“站点”(在本例中为资源管理器)之间有很多双向通信。特别是如果扩展是 shell 命名空间扩展。根据扩展的类型,如果没有合适的生态系统来托管它,就不能仅仅加载 COM 扩展。
-
考虑改写上面的图表。在图中,绿色框不能充当COM 代理项。根据定义,COM 代理是一个 Windows 进程,但您的绿框必须是一个进程内 COM 服务器(即 .DLL),以便加载到 64 位 Windows 资源管理器中.
-
@BTownTKD,只要您不必处理 COM 无法编组的数据,您就可以这样做。并且您的瘦 64 位 DLL 可能需要处理来自 32 位代理的请求。例如,您必须将在 32 位 DLL(使用
CoCreateInstance或类似)中创建 Explorer 对象转换为对 64 位 DLL 的请求(如果您使用的是IClassFactory::CreateInstance,这基本上只需要您获取工厂从 64 位 DLL 而不是CoGetClassObject)。
标签: c++ windows com 32bit-64bit shell-extensions