COM学习(二)——COM的注册和卸载
来源:互联网 发布:淘宝商城公主裙 编辑:程序博客网 时间:2024/06/03 16:37
COM组件是跨语言的,组件被注册到注册表中,在加载时由加载函数在注册表中查找到对应模块的路径并进行相关加载。它的存储规则如下:
1. 在注册表的HKEY_CLASSES_ROOT中以模块名的方式保存着COM模块的GUID,比如HKEY_CLASSES_ROOT\ADODB.Error\CLSID键中保存着模块ADODB.Error的GUID为{00000541-0000-0010-8000-00AA006D2EA4}
2. 在HKEY_CLASSES_ROOT\CLSID中以GUID为项名保存着对应组件的详细信息,比如之前的{00000541-0000-0010-8000-00AA006D2EA4}这个GUID在注册表中的位置为HKEY_CLASSES_ROOT\CLSID\{00000541-0000-0010-8000-00AA006D2EA4}\InprocServer32\项的默认键中保存着模块所在路径为%CommonProgramFiles%\System\ado\msado15.dll
一般的COM模块都是使用regsvr32程序注册到注册表中,该程序在注册时会在模块中查找DllRegisterServer函数,卸载时调用模块中提供的DllUnregisterServer,所以要实现注册的功能主要需要实现这两个函数
这两个函数的原型如下:
STDAPI DllRegisterServer();STDAPI DllUnregisterServer();
通过VS的F12功能查找STDAPI 的定义如下:
#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
在查看STDAPICALLTYPE得到如下结果:
#define STDAPICALLTYPE __stdcall
所以这个宏展开也就是
extern "C" HRESULT __stdcall DllRegisterServer();
为了实现注册功能,首先定义一个全局的变量,用来表示需要写入到注册表中的项
const TCHAR *g_regTable[][3] = { {_T("SOFTWARE\\ComDemo"), 0, _T("ComDemo")}, {_T("SOFTWARE\\ComDemo\\InporcServer32"), 0, (const TCHAR*)-1}
这三项分别为注册表项,注册表项中的键名和键值,当键名为0时会创建一个默认的注册表键,最后一个-1我们会在程序中判断,如果键值为-1,那么值取为模块的路径
下面是注册的函数
STDAPI DllRegisterServer(){ HKEY hKey = NULL; TCHAR szFileName[MAX_PATH] = _T(""); GetModuleFileName(g_hDllIns, szFileName, MAX_PATH); int nCount = sizeof(g_regTable) / sizeof(*g_regTable); for (int i = 0; i < nCount; i++) { LPCTSTR pszKeyName = g_regTable[i][0]; LPCTSTR pszValueName = g_regTable[i][1]; LPCTSTR pszValue = g_regTable[i][2]; if (pszValue == (const TCHAR*)-1) { pszValue = szFileName; } long err = RegCreateKey(HKEY_LOCAL_MACHINE, pszKeyName, &hKey); if (err != ERROR_SUCCESS) { return SELFREG_E_LAST; } err = RegSetValueEx(hKey, pszValueName, 0, REG_SZ, (const BYTE*)pszValue, _tcslen(pszValue) * sizeof(TCHAR)); if (err != ERROR) { return SELFREG_E_LAST; } RegCloseKey(hKey); } return S_OK;}
在程序中会循环读取上述全局变量中的值,将值保存到注册表中,在上面的代码中有一句sizeof(g_regTable) / sizeof(*g_regTable);
这个是算需要循环多少次,第一个sizeof得到的是这个二维数组的总大小。在C语言中我们说二维数组可以看做是由一维数组组成的,这个二维数组可以看成是由两个一维数组——一个由3个const TCHAR *成员组成的一维数组组成。所以*g_regTab自然就是这个一维数组的首地址,第二个sizeof就是这个一维数组的大小,两个相除得到的就是一维数组的个数。
卸载函数如下:
STDAPI DllUnregisterServer(){ int nCount = sizeof(g_regTable) / sizeof(*g_regTable); for (int i = nCount - 1; i >= 0; i--) { LPCTSTR pszKeyName = g_regTable[i][0]; long err = RegDeleteKey(HKEY_LOCAL_MACHINE, pszKeyName); if (err != ERROR_SUCCESS) { return SELFREG_E_LAST; } } return S_OK;}
至此已经实现注册和卸载函数。后面就可以直接使用regsvr32这个程序进行注册和卸载了.
- COM学习(二)——COM的注册和卸载
- com+组件的注册,卸载和管理
- com组件注册与卸载
- COM 学习(五)——编译、注册、调用
- COM学习(三)——COM的跨语言
- Com 组件的装载和卸载
- Com 组件的装载和卸载 .
- Com 组件的装载和卸载
- Com 组件的装载和卸载
- COM学习笔记(二)
- COM学习笔记(二)
- 连接COM与.NET的桥梁(二)——COM服务器的P/Invoke方式
- 【转载】 javaweb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册 - 孤傲苍狼 - 博 http://www.cnblogs.com/xdp-gacl/
- OLE/COM 对象查看器——查看已注册控件的属性和方法(自己整理)
- COM组件开发(二)——COM应用模型及COM库
- 我的注册——https://www.ibm.com/
- COM学习(一)——COM基础思想
- COM学习(四)——COM中的数据类型
- 远程仓库
- 搜索框模糊匹配下拉显示
- 第三单元(第二十三课到第二十六课)、AGGREGATE FUNCTIONS
- checkStyle、findbugs、PMD各自特点
- 《大话设计模式》读书笔记之C++实现--chapter15抽象工厂模式
- COM学习(二)——COM的注册和卸载
- 隐马尔科夫(HMM)模型
- python中出现非正定“Input X must be non-negative”的问题
- HDPCD-Java-复习笔记(18)
- Java---String类
- Java--多线程
- create-react-app路由的实现原理
- Java--线程的常用方法
- 3435==1853==3488 三连发