不需要注册即可使用DLL中的COM对象

17

在非托管的C++代码中,是否可能在不注册的情况下使用来自DLL的COM对象?

3个回答

11

是的,如果它在内部不依赖其他已注册的对象。

  1. 您可以使用 LoadLibrary 加载 DLL。
  2. 您需要调用 GetProcAddress 获取其 DllGetClassObject 函数指针。
  3. 您可以通过调用 DllGetClassObject 来获取感兴趣的 CLSIDIClassFactory 指针。
  4. 使用 IClassFactory::CreateInstance 来实例化 coclass。

6
在调用DllGetClassObject之前,请确保你在正确的公寓中。即使如此,你也不会为特定对象模型接口获得编组。即使C++ COM对象本身实现了IMarshalIProvideClassInfo,如果你提供了实现任何这些接口的对象(例如事件分发接口),你仍需要执行相同的操作。因为这些原因和许多其他原因,这是一种不好的做法。你应该使用注册自由的COM。 - acelent

8

5

假设 COM DLL 需要注册,但应用程序没有管理员权限。这里有一个简单的技巧可以在 HKEY_CURRENT_USER 下注册 DLL,而不需要管理员权限:

  1. 使用 LoadLibrary 加载 COM DLL。
  2. 调用 GetGetProcAddress 获取 DllRegisterServer 的地址。
  3. 调用 RegOverridePredefKey 进行临时的注册表重定向:将 HKEY_LOCAL_MACHINE 重定向到 HKEY_CURRENT_USER,并将 HKEY_CLASSES_ROOT 重定向到 HKEY_CURRENT_USER\Software\Classes
  4. 调用步骤2中获取的 DllRegisterServer
  5. 撤销注册表重定向。
  6. 像平常一样使用 COM 服务器,它现在已在 HKEY_CURRENT_USER 下注册。

2
“easy” hack。虽然聪明。 - Dmytro
RegOverridePredefKey 的文档说明新的 HKEY 不能是预定义键之一,所以我不确定如何进行第三步。我应该打开一个现有的注册表键吗? - phetdam
我最终使用了另一个帖子的答案,并成功调用了OaEnablePerUserTLibRegistrationDllRegisterServer之前。只需要将HKEY_CLASSES_ROOT映射到HKEY_CURRENT_USER\Software\Classes即可。但是我可能漏掉了一些东西。 - phetdam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接