通讯与通讯CoGetClassObject()
我在使用 CoGetClassObject()
时遇到了一些问题。
我有一个应用程序必须使用特定版本的一些 DLL, 但它们也存在于更新版本的系统中。
所以我开始挂接 CoCreateInstance()
和 loadLibrary()
,我认为这很好。 问题是两个版本的DLL都被加载了。
因此,我认为 CoGetClassObject() 是问题/解决方案,因为它提供了一个指向与 CLSID 关联的对象接口的指针,该 CLSID 包含应用程序必须在旧版本中使用的 DLL。
但我不知道这个函数“做什么”,那么我怎样才能“覆盖”这个函数呢?
谢谢。
PS:我是COM编程的新手。
I have a little problem with CoGetClassObject()
.
I have an application which must use some DLLs of a specific version,
but they are also present in the system, in a more recent version.
So I start hooking the CoCreateInstance()
and loadLibrary()
, which I guess are good.
The problem is that the DLLs in the two versions are loaded.
So I think that CoGetClassObject()
is the problem/solution because it provides a pointer to an interface of an object associated with a CLSID containing a DLL that the application must use in an older version.
But I don't know what this function "does", so how can I "override" this function ?
thanks.
PS : I'm new in the COM programming.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
CoGetClassObject() 只完成 CoCreateInstance() 一半的工作。它返回一个类工厂。 CoCreateInstance() 然后调用 IClassFactory::CreateInstance() 并释放 IClassFactory。仅当您需要创建某个组件类的许多对象并希望对其进行优化时,您才会使用它。它避免了一遍又一遍地创建和释放工厂的成本。
您可能忽略了这个问题的一个更简单的解决方案。您只需将新版本的 COM 服务器 DLL 复制到与客户端 EXE 相同的目录中即可。并创建一个名为“app.exe.local”的零字节文件,其中“app”是 EXE 的名称。这足以强制加载复制的 DLL,而不是注册表指向的 DLL。有关 DLL 重定向的 MSDN 库文章在这里。
CoGetClassObject() simply does half the job that CoCreateInstance() does. It returns a class factory. CoCreateInstance() then call IClassFactory::CreateInstance() and releases the IClassFactory. You would only use it if you have a need to create many objects of a certain coclass and want to optimize that. It avoids the cost of creating and releasing the factory over and over again.
You are possibly overlooking a far simpler solution to this problem. You can simply copy the new version of the COM server DLL into the same directory as the client EXE. And create a zero byte file with the name "app.exe.local" where "app" is the name of the EXE. That's enough to force that copied DLL to be loaded instead of the one that the registry points to. The MSDN Library article about DLL redirection is here.
非常简单的解释是
CoGetClassObject()
打开HKCR\CLSID\{ClassId}
并查看InProcServer32
或LocalServer32
取决于传递的CLSCTX_*
值 - 即 COM 服务器路径。一旦找到 COM 服务器文件路径,就会加载(
LoadLibraryEx()
带有LOAD_WITH_ALTERED_SEARCH_PATH
标志(如果是 in-proc)或CreateProcess()
(如果是 in-proc)进程外)COM 服务器。然后,它为进程内服务器查找并调用 DllGetClassObject(),或者等待直到为进程外服务器注册类工厂。这当然会忽略 DCOM 等内容。您可以使用 Process Monitor 实用程序更好地了解它如何遍历注册表。
The very simple explanation is
CoGetClassObject()
opensHKCR\CLSID\{ClassId}
and looks atInProcServer32
orLocalServer32
depending on whatCLSCTX_*
value is passed - that is the COM server path.Once it find a COM server file path is loads (
LoadLibraryEx()
withLOAD_WITH_ALTERED_SEARCH_PATH
flag in case of in-proc orCreateProcess()
in case of out-proc) the COM server. Then it locates and callsDllGetClassObject()
for in-proc servers or waits until a class factory is registered for out-proc servers.This of course ignores stuff like DCOM etc. You can get a better idea of how it traverses the registry using Process Monitor utility.
如果您想加载特定的 COM DLL,无论是否安装了较新的版本,也无论旧的 DLL 位于何处,则只需忽略
CoCreateInstance()
和CoGetClassObject()< /代码> 完全。通过
。无论如何,这都是LoadLibrary()
自行加载旧版 DLL,然后直接调用其导出的DllGetClassObject()
函数来获取 DLL 的IClassFactory
接口,然后调用 <根据需要编写代码>IClassFactory::CreateInstance()CoCreateInstance()
和CoGetClassObject()
在内部执行的操作,但这绕过了它们执行的注册表查找以确定要加载的 DLL 路径。If you want to load a specific COM DLL regardless of whether there is a newer version installed, and regardless of where the older DLL is located, then simply ignore
CoCreateInstance()
andCoGetClassObject()
altogether. Load the older DLL yourself viaLoadLibrary()
, then call its exportedDllGetClassObject()
function directly to get the DLL'sIClassFactory
interface, then callIClassFactory::CreateInstance()
as needed. This is allCoCreateInstance()
andCoGetClassObject()
do internally anyway, but this bypasses the Registry lookups they perform to determine the DLL path to load.