将 CoCreateInstance 重定向到假实现

Redirecting CoCreateInstance to fake implementation

鉴于一些现有代码调用 CoCreateInstance 来创建已注册 COM 对象的实例,是否有办法重定向这些调用以创建不同的实例?

这个想法是在同一个进程中(出于测试目的),在不改变原始代码或影响任何其他进程的情况下,当它请求系统提供的 CLSID_ShellLink(例如)时,它会创建实现相同接口的自定义类型(在相同代码库中实现)的实例,而不是它通常创建的 "real" 实例。

澄清一下:我正在寻找可以说 "hey CoCreateInstance, call this local thing to create an instance first before going to look at the registrations" 的 API 电话。而且它必须是可以通过编程方式完成的事情,而不是通过操作注册表或配置文件;它需要在代码中切换。

由于 COM 创建是基于 CLSID 注册的,您可以用自己的代理覆盖已知的 CLSID class。然而,这不受支持,可能会导致未定义的行为。此外,这将取决于调用 CoCreateInstance 的方式(CLSCTX 枚举)。

这似乎是 COM 会在内部实现的东西,因为它有查找表和远程计算机挂钩以及各种其他奇怪而奇妙的东西。它基本上只是一种不同类型的对象工厂。

不过,至少目前,我只是使用了一个 API 拦截器来挂钩 CoCreateInstance 本身并将其重定向到自定义函数。有效。

我会把它打开一段时间,以防万一有人知道在 COM 内部执行此操作的正确方法™。

如果您正在创建的对象正在处理中,并且如果您可以在您正在谈论的过程中调用 CoRegisterClassObject,则可以为特定对象注册您自己的 class 工厂...也取决于调用 CoCreateInstance 时使用的标志。

I'll leave this open for a while longer yet in case anyone does know the Right Way™ to do this within COM itself.

上面提到了其中一种方法,当您需要在范围内重新定义实例化时特别有用。

另一种真正的 COM 方法是使用 "treat as" 仿真。 CoTreatAsClass function on MSDN features the API itself, and Remarks section gives a good description.

启用后,给定 CLSID 上对 CoCreateInstance 的请求将被重定向到新仿真 CLSID