一个COM组件在使用前必须首先注册。所谓“注册”,也就是向系统注册表的相应位置写入一些数据。这些数据可以完成guid与Dll的绝对路径的一一对应,也就是说可以帮助程序通过guid找到Dll的位置。
GUID概念:
GUID(globally unique identifier)是一个128位的数。用于保证每一个接口和组件在时间和空间上都是全球唯一的一个标识符。为保证空间唯一性,根据机器上网卡的MAC地址再加上一定的算法生成的唯一的48位值序列;为保证时间上的唯一性,每个GUID值具有一个60位的时间戳。这个时间戳表示的是自1852年10月15号00:00:00以来以100纳秒为时间间隔的计数值。这样可以保证3400年GUID值仍然是唯一的。下面是GUID的定义和一个示例:
typedef struct _GUID { unsigned long Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[8]; } GUID; // {364ede61-08ac-43ec-8861-15f5f9f4ced1}
微软提供了两个建立GUID的程序,一个时UUIDGEN.EXE,该程序是命令行方式的;另一个则是GUIDGEN.EXE,是一个示例性的VC++对话框应用。
DEFINE_GUID可以使用GUIDGEN.EXE来生成一个GUID。
注册表:
组件可以用CLSID作为索引在Windows的注册表中发布包含他们的DLL文件名称。CoCreateInstance将用CLSID作为关键字在注册表中查找所需要的文件名称。注册表是一个由许多元素构成的层次结构。每一个元素均被称作是一个关键字。每一个关键字可以包含一系列子关键字、一系列命名的值及/或一个未命名的值。COM只使用了注册表的一个分支:HKEY_CLASSES_ROOT;在此关键字之下,可以看到有一个CLSID关键字。在CLSID关键字之下列有系统中安装的所有组件的CLSID。
对于每一个CLSID关键字,我们现在关心的只是它的一个子关键字InprocServer32。
此子关键字的缺省值是组件所在的Dll文件路径名称。
另一个子关键字ProgID指的是程序员给某个CLSID指定的一个程序员易记的名称。
如何注册COM组件:
由于DLL知道它所包含的组件,因此DLL可以完成这些信息的注册。在DLL中一定要处处如下两个函数:
DllRegisterServer();// 完成注册组件
DllUnRegisterServer();// 完成反注册组件
用户可以使用程序REGSVR32.EXE来注册某个组件。方法是使用命令行:regsvr32/u testDll.dll(反注册) regsvr32 testDll.dll(注册)。
一个典型的注册COM组件Dll必须导出如下五个函数:
1)DllMain:Dll的入口函数,完成一些Dll的初始化工作(DirectShow实现的是DllEntryPoint);
2)DllGetClassObject:用于获得类工厂指针;
3)DllCanUnloadNow: 系统空闲时会调用这个函数,以确定是否可以卸载Dll;
4)DllRegisterServer:将COM组件注册到注册表中;
5)DllUnregisterServer: 删除注册表中COM组件的注册信息。
所以,要想完成注册,关键就是对DllRegisterServer();DllUnRegisterServer();两个函数的实现,下面将详细介绍如何实现这两个函数:
//g_module为DLL的实例句柄 //CLSID_INNER_COM为组件的CLSID //const char g_friend_name_inner [] = "inner_com_test"; //const char g_ver_indprog_id_inner [] = "inside.com.chapter.7.inner"; //const char g_prog_id_inner [] = "inside.com.chapter.7.inner.1"; STDAPI DllRegisterServer(void) { HRESULT hr = RegisterServer(g_module,CLSID_INNER_COM, g_friend_name_inner,g_ver_indprog_id_inner,g_prog_id_inner); return hr; }
//Register the component in the registry HRESULT RegisterServer(HMODULE hModule, const CLSID& clsid, const char* szFriendlyName, const char* szVerIndProgID, const char* szProgID) { //Get the Server location char szModule[512]; DWORD dwResult = ::GetModuleFileName(hModule,szModule,sizeof(szModule)/sizeof(char)); assert(dwResult!=0); //Convert the CLSID into a char char szCLSID[CLSID_STRING_SIZE]; CLSIDtochar(clsid,szCLSID,sizeof(szCLSID)); //Build the key CLSID\\{} char szKey[64]; strcpy(szKey,"CLSID\\"); strcat(szKey,szCLSID); //Add the CLSID to the registry setKeyAndValue(szKey,NULL,szFriendlyName); //Add the Server filename subkey under the CLSID key setKeyAndValue(szKey,"InprocServer32",szModule); setKeyAndValue(szKey,"ProgID",szProgID); setKeyAndValue(szKey,"VersionIndependentProgID",szVerIndProgID); //Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT setKeyAndValue(szVerIndProgID,NULL,szFriendlyName); setKeyAndValue(szVerIndProgID,"CLSID",szCLSID); setKeyAndValue(szVerIndProgID,"CurVer",szProgID); //Add the versioned ProgID subkey under HKEY_CLASSES_ROOT setKeyAndValue(szProgID,NULL,szFriendlyName); setKeyAndValue(szProgID,"CLSID",szCLSID); return S_OK; }
STDAPI DllUnregisterServer(void) { HRESULT hr = UnRegisterServer(CLSID_INNER_COM,g_ver_indprog_id_inner,g_prog_id_inner); return hr; }
//Remove the component from the register HRESULT UnRegisterServer(const CLSID& clsid, // Class ID const char* szVerIndProgID, // Programmatic const char* szProgID) // IDs { //Convert the CLSID into a char. char szCLSID[CLSID_STRING_SIZE]; CLSIDtochar(clsid,szCLSID,sizeof(szCLSID)); //Build the key CLSID\\{} char szKey[64]; strcpy(szKey,"CLSID\\"); strcat(szKey,szCLSID); //Delete the CLSID key - CLSID\{} LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT,szKey); assert((lResult == ERROR_SUCCESS) || (lResult == ERROR_FILE_NOT_FOUND)); //Delete the version-independent ProgID Key lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT,szVerIndProgID); assert((lResult == ERROR_SUCCESS) || (lResult == ERROR_FILE_NOT_FOUND)); //Delete the ProgID key. lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT,szProgID); assert((lResult == ERROR_SUCCESS) || (lResult == ERROR_FILE_NOT_FOUND)); return S_OK; }
相关推荐
"com组件注册查看器"是一个专门用于查看计算机上已注册的COM组件的工具。通过这款查看器,用户可以枚举并查看所有已注册的COM组件的相关信息,这包括但不限于组件的CLSID(Class ID)、ProgID(Program ID)、文件...
COM+组件注册是Windows操作系统中用于管理分布式组件的一种机制,它扩展了传统的COM(Component Object Model)技术,提供了更高级别的服务,如事务处理、安全性和资源管理。COM+组件通常用于构建分布式应用程序,使...
注册COM组件是使其能够被系统识别并可供其他程序使用的必要步骤。 在Windows操作系统中,注册COM组件通常有两种方法: 1. **调用regsvr32.exe**: 这是传统且最直接的方法,通过命令行执行`regsvr32.exe`命令,将...
13.如何取消COM服务组件注册?(Visual C++编程 源代码)13.如何取消COM服务组件注册?(Visual C++编程 源代码)13.如何取消COM服务组件注册?(Visual C++编程 源代码)13.如何取消COM服务组件注册?(Visual C++...
在给定的“com口组件与com口注册工具32/64位”压缩包中,包含了以下关键内容: 1. **COM口组件DLL**:DLL (Dynamic Link Library) 文件是一种包含可由多个程序同时使用的代码和数据的库。在本案例中,这个DLL文件...
本文将深入探讨C#中如何创建、注册COM组件以及如何在其他应用程序中调用这些组件,这对于初学者来说是一次宝贵的学习机会。 首先,我们需要理解什么是COM组件。COM是微软提出的一种二进制标准,它允许不同语言编写...
注册COM组件是将这些组件与系统进行关联的过程,以便Windows能够识别并正确地调用它们。 注册COM组件通常涉及到以下步骤: 1. **创建COM组件**:开发者使用编程语言(如C++、VB或Delphi)创建一个实现了特定接口的...
- **系统维护**:清理无效或冲突的COM组件注册,有助于优化系统性能和稳定性。 - **安全审计**:检查未知或可疑的COM组件,防范潜在的安全风险。 总之,COM组件查看器是一款强大的工具,能够提供对系统中COM组件的...
易语言组件注册工具OCX注册DLL注册源码,彗星注册组件,彗星卸载组件,彗星信息框,GetProcAddress,LoadLibrary,FreeLibrary,CallWindowProc,MessageBox,GetShortPathName
安装了VS(我用的vs2012 64位) gacutil.exe路径 C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools ...3、regasm dll文件名.dll /tlb:dll文件名.tlb 然后回车,显示注册成功
本篇文章将深入探讨如何使用Delphi来实现COM组件的自动注册与卸载。 首先,COM组件的注册是将其元数据(如类ID、接口ID等)写入系统注册表的过程,以便其他应用程序能够找到并使用这些组件。在Delphi中,我们通常会...
1. 注册COM组件:编译运行项目,生成dll文件,并自动注册到系统中。 2. 使用MFC调用COM组件:使用ClassWizard生成包装类,使用类型库中的MFC类来调用COM组件。 3. 使用COM组件:在对话框程序中,引入头文件#...
在本实例中,我们将探讨如何使用Visual Studio 2015(VS 2015)和C#语言来创建一个COM组件,并了解其注册和使用的步骤。 首先,创建COM组件需要一个支持COM的项目类型。在VS 2015中,我们可以创建一个“类库”项目...
每个COM组件都必须注册到系统中才能被其他应用程序所使用,这个过程通常通过`regsvr32`命令完成。 #### 实现步骤 根据题目中的部分描述和内容,下面将详细介绍如何在C#中调用COM组件。 ##### 步骤一:注册COM组件...
- 使用regasm工具将.NET程序集注册为COM组件,使其能够在系统注册表中注册组件信息。 - 上述步骤后,COM组件就可以被其他应用程序通过其ProgID进行创建和使用了。 ***组件的调用示例 - 在VBScript中,可以使用...
下面我们将详细探讨如何在VB.NET中创建和注册一个COM组件。 1. **创建VB.NET类库项目** 首先,我们需要在Visual Studio中创建一个新的VB.NET Class Library项目。这可以通过选择“文件” > “新建” > “项目”,...
通过这篇文章,读者可以了解COM组件的基本概念,如何新建一个Visual C#工程,编写导出接口,创建事件接口,创建具体类,注册COM组件,并使用VC6.0调用COM组件。 九、注意事项 在编写COM组件时,需要注意以下几点:...
### 检索COM类工厂中组件注册失败的解决方法 在进行软件开发或系统管理过程中,有时会遇到“检索COM类工厂中组件注册失败”的问题,尤其在尝试注册Office组件(如Microsoft Excel)时较为常见。这类问题往往与...
通过一个简单的组件实现两个接口,CoCreateInstance 调用 DLLGetClassObject返回相应的组件类厂 类厂调用CreateInstance创建组件 用DLLRegisterServer向注册表中加一个组件ID,前提是要对注册表中CLSID下的结构有...
总的来说,通过C语言实现COM组件涉及接口定义、方法实现、注册和注销组件,以及处理多线程和进程间通信等问题。这是一项技术性很强的任务,但理解和掌握COM组件的开发对于Windows平台的软件开发人员来说是至关重要的...