我有一个COM类(例如,CLSID_WidgetFactory
),我想让我的进程中的任何人都可以调用它:
CoCreateInstance(CLSID_Widget, ...);
但我希望无需注册即可将其提供,或将其包含在免注册的COM程序集清单中。
我有:
clsid
(CLSID_Widget
)IClassFactory
实施如何在COM基础架构中注册这些内容,以便我的进程中的任何人都可以创建COM对象?
显然我想要做到这一点:
HKLM\Software\Classes
注册表配置单元HKCU\Software\Classes
hive 从概念上讲,我将拥有我的classID和工厂对象:
class WidgetFactory : ComObject, IClassFactory
{
//IClassFactory methods
HRESULT CreateInstance(IUnknown unkOuter, Guid iid, out obj)
{
Widget widget = new Widget();
HRESULT hr = widget.QueryInterface(iid, out obj);
return hr;
}
}
然后我想注册我的班级工厂:
Guid CLSID_Widget = "{0677445E-EA9B-447A-AF2E-CCD86E49CED0}";
IClassFactory factory = new WidgetFactory();
RegisterClassFactory(CLSID_Widget, factory);
剩下的就是弄清楚如何在内存中注册COM类:
void RegisterClassFactory(Guid clsid, IClassFactory classfactory)
{
//...
}
注意:我知道答案。但我无法弄清楚会触发命中的正确搜索词组。
奖金阅读
答案 0 :(得分:3)
您可以将CoRegisterClassObject
与CLSCTX_INPROC_SERVER
和REGCLS_MULTIPLEUSE
一起使用。
DWORD RegisterClassFactory(Guid clsid, IClassFactory factory)
{
/*
Register a COM class in-memory.
Any requests by COM to create object clsid will use the
class factory given by factory.
This means that a COM object does not have to be registered
in the registry in order to use it. Nor does it have
to be included in an application manifest.
Public domain: No attribution required.
*/
DWORD dwCookie; //returned cookie can be later used to delete the registration
HRESULT hr = CoRegisterClassObject(
clsid, // the CLSID to register
factory, // the factory that can construct the object
CLSCTX_INPROC_SERVER, // can only be used inside our process
REGCLS_MULTIPLEUSE, // it can be created multiple times
out dwCookie // cookie we can later use to delete the registration
);
OleCheck(hr);
return dwCookie;
}
现在你进程中的任何人都可以创建这个任意的COM对象(即使它没有在注册表中注册,也没有包含在程序集清单中):
CoCreateInstance(CLSID_Widget, null, CLSCTX_INPROC_SERVER, IID_IUnknown, out unk);
如果您要注册多个班级,则可以合并REGCLS_SUSPENDED
标记(例如,使用或运算符|
):
暂停对指定CLSID的注册和激活请求,直到调用CoResumeClassObjects为止。这通常用于为可以注册多个类对象的服务器注册CLSID,以便通过单次调用SCM来减少整体注册时间,从而缩短服务器应用程序启动时间,无论为服务器注册了多少个CLSID
注意此标志可防止应用程序关闭和尝试注册COM类的应用程序之间可能存在竞争条件的COM激活错误。
然后调用CoResumeClassObjects
一次以原子方式注册类。
如果您打算从DLL执行此操作,则应确保DLL在应用程序启动时提供注册入口点。或者只是不使用简历并暂停类对象功能。
答案 1 :(得分:2)
CoRegisterClassObject
会为给定的CLSID
注册一个班级工厂,并将其提供给您的流程的来电者,但只是在注册公寓(也许您可以在几个公寓注册)。
CoCreateInstance
会成功,就好像CLSID
通过注册表以通常方式注册一样。
AFAIR您对Delphi感兴趣,但无论如何this ATL C ++类是一个示例代码段,显示使用CoRegisterClassObject
临时注册CLSID
第三方CoCreateInstance
在局部变量范围内:
{
BEGIN_OBJECT_MAP(g_pObjectMap)
OBJECT_ENTRY(__uuidof(CSplitterMediaObject), CSplitterMediaObject)
// ...
END_OBJECT_MAP()
CLocalObjectMap ObjectMap(g_pObjectMap, TRUE);
// ...
// Someone calls CoCreateInstance(__uuidof(CSplitterMediaObject), ...
// here and the call succeeds as if the class is registered
}