通讯与通讯CoGetClassObject()

发布于 2024-11-25 15:31:36 字数 385 浏览 0 评论 0原文

我在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

枫林﹌晚霞¤ 2024-12-02 15:31:36

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.

醉梦枕江山 2024-12-02 15:31:36

非常简单的解释是 CoGetClassObject() 打开 HKCR\CLSID\{ClassId} 并查看 InProcServer32LocalServer32取决于传递的 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() opens HKCR\CLSID\{ClassId} and looks at InProcServer32 or LocalServer32 depending on what CLSCTX_* value is passed - that is the COM server path.

Once it find a COM server file path is loads (LoadLibraryEx() with LOAD_WITH_ALTERED_SEARCH_PATH flag in case of in-proc or CreateProcess() in case of out-proc) the COM server. Then it locates and calls DllGetClassObject() 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.

等数载,海棠开 2024-12-02 15:31:36

如果您想加载特定的 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() and CoGetClassObject() altogether. Load the older DLL yourself via LoadLibrary(), then call its exported DllGetClassObject() function directly to get the DLL's IClassFactory interface, then call IClassFactory::CreateInstance() as needed. This is all CoCreateInstance() and CoGetClassObject() do internally anyway, but this bypasses the Registry lookups they perform to determine the DLL path to load.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文