本篇介绍COM注册TypeLib,CLR程序调用COM组件;注册ProgID及ProgID和CLSID相互映射等。
1. 注册TypeLib
IDL在MIDL编译后会生成一个.tlb文件,这个文件包含TypeLibrary信息,为使我们写的COM组件供.NET或VB等程序调用,注册类型库是必须的。我们可以直接注册生成的tlb文件,但为了便于部署,可以将tlb文件作为资源嵌dll中。
新建一个rc文件,添加如下代码:
这里的TypeLib的ID通常为1,注册TypeLib的时候直接使用dll路径及文件名即可,否则需要在路径文件名后加上"\TypeLib在rc文件中的ID"。
注册TypeLib可以使用直接写注册表的方式和调用API注册,建议使用后者,因为调用API时会对TypeLib的合法性进行验证。
LoadTypeLibEx函数会加载COM组件,取得ITypeLib接口实例并注册TypeLib。
LIBID_BEGINNINGCOMLib是MIDL编译idl文件时从idl文件获得的library的ID。
COM类型库注册后会在注册表中写入如下信息:
2. CLR调用COM组件
CLR调用COM组件可以用tlbimp工具生成代理类,也可以直接在VS中添加引用,这里我们仅实验后者。
VS中新建一个Console Application,添加引用,COM列表中,Componment Name列中列出了我们刚刚创建的COM组建,添加BeginningCOMLib类型库。然后编写代码:
运行,输出了我们预期的结果。64位系统要注意,如果COM组件编译为x86平台,.NET程序也要编译为x86平台,否则会抛出类没有注册的错误。
3. 注册ProgID
ProgID和CLSID基本上是一一对应的,CLSID是GUID形式,能保证其唯一性;而ProgID比较易读易记,并且脚本语言一般用ProgID来调用COM组件。
注册ProgID只需在注册表中写入一些键值即可,ProgID习惯的命名方式是组件.版本。为注册ProgID,RegTable数组的内容如下:
可以使用ProgIDFromCLSID函数,将CLSID转换为ProgID;使用CLSIDFromProgID将ProgID转换为CLSID,具体使用见MSDN。
COM有关的注册表内容:http://msdn.microsoft.com/en-us/library/ms678477(VS.85).aspx
源文件下载:BeginningCOM3.zip
1. 注册TypeLib
IDL在MIDL编译后会生成一个.tlb文件,这个文件包含TypeLibrary信息,为使我们写的COM组件供.NET或VB等程序调用,注册类型库是必须的。我们可以直接注册生成的tlb文件,但为了便于部署,可以将tlb文件作为资源嵌dll中。
新建一个rc文件,添加如下代码:
1 TypeLib "Debug\\BeginningCOM.tlb"
这里的TypeLib的ID通常为1,注册TypeLib的时候直接使用dll路径及文件名即可,否则需要在路径文件名后加上"\TypeLib在rc文件中的ID"。
注册TypeLib可以使用直接写注册表的方式和调用API注册,建议使用后者,因为调用API时会对TypeLib的合法性进行验证。
//register typelib
ITypeLib *pTypeLib;
hr = LoadTypeLibEx(szFileName, REGKIND_REGISTER, &pTypeLib);
pTypeLib -> Release();
//unregister type
UnRegisterTypeLib(LIBID_BEGINNINGCOMLib, 1, 0, LANG_NEUTRAL, SYS_WIN32);
ITypeLib *pTypeLib;
hr = LoadTypeLibEx(szFileName, REGKIND_REGISTER, &pTypeLib);
pTypeLib -> Release();
//unregister type
UnRegisterTypeLib(LIBID_BEGINNINGCOMLib, 1, 0, LANG_NEUTRAL, SYS_WIN32);
LoadTypeLibEx函数会加载COM组件,取得ITypeLib接口实例并注册TypeLib。
LIBID_BEGINNINGCOMLib是MIDL编译idl文件时从idl文件获得的library的ID。
COM类型库注册后会在注册表中写入如下信息:
[HKEY_CLASSES_ROOT\TypeLib\{D9161D4D-66C0-4AE6-9264-C322BDE034C7}\1.0]
@="BeginningCOMLib"
[HKEY_CLASSES_ROOT\TypeLib\{D9161D4D-66C0-4AE6-9264-C322BDE034C7}\1.0\0\win32]
@="E:\\Projects\\BeginningCOM\\Debug\\BeginningCOM.dll"
//...
@="BeginningCOMLib"
[HKEY_CLASSES_ROOT\TypeLib\{D9161D4D-66C0-4AE6-9264-C322BDE034C7}\1.0\0\win32]
@="E:\\Projects\\BeginningCOM\\Debug\\BeginningCOM.dll"
//...
2. CLR调用COM组件
CLR调用COM组件可以用tlbimp工具生成代理类,也可以直接在VS中添加引用,这里我们仅实验后者。
VS中新建一个Console Application,添加引用,COM列表中,Componment Name列中列出了我们刚刚创建的COM组建,添加BeginningCOMLib类型库。然后编写代码:
static void Main(string[] args)
{
BeginningCOM bc = new BeginningCOM();
Console.WriteLine(bc.Sum(1, 2));
bc.Num = int.MaxValue;
Console.WriteLine(bc.Num);
Console.ReadKey();
}
{
BeginningCOM bc = new BeginningCOM();
Console.WriteLine(bc.Sum(1, 2));
bc.Num = int.MaxValue;
Console.WriteLine(bc.Num);
Console.ReadKey();
}
运行,输出了我们预期的结果。64位系统要注意,如果COM组件编译为x86平台,.NET程序也要编译为x86平台,否则会抛出类没有注册的错误。
3. 注册ProgID
ProgID和CLSID基本上是一一对应的,CLSID是GUID形式,能保证其唯一性;而ProgID比较易读易记,并且脚本语言一般用ProgID来调用COM组件。
注册ProgID只需在注册表中写入一些键值即可,ProgID习惯的命名方式是组件.版本。为注册ProgID,RegTable数组的内容如下:
LPCTSTR RegTable[][3] =
{
{L"CLSID\\{586CDC7B-09F1-4f44-A110-F0E604AED81E}", 0, L"BeginningCOM"},
{L"CLSID\\{586CDC7B-09F1-4f44-A110-F0E604AED81E}\\InprocServer32", 0, (LPCTSTR)-1},
{L"CLSID\\{586CDC7B-09F1-4f44-A110-F0E604AED81E}\\InprocServer32", L"ThreadingModel", L"Both"},
{L"CLSID\\{586CDC7B-09F1-4f44-A110-F0E604AED81E}\\ProgID", 0, L"BeginningCOM.1"},
{L"BeginningCOM.1", 0, L"COM ProgID sample"},
{L"BeginningCOM.1\\CLSID", 0, L"{586CDC7B-09F1-4f44-A110-F0E604AED81E}"}
};
{
{L"CLSID\\{586CDC7B-09F1-4f44-A110-F0E604AED81E}", 0, L"BeginningCOM"},
{L"CLSID\\{586CDC7B-09F1-4f44-A110-F0E604AED81E}\\InprocServer32", 0, (LPCTSTR)-1},
{L"CLSID\\{586CDC7B-09F1-4f44-A110-F0E604AED81E}\\InprocServer32", L"ThreadingModel", L"Both"},
{L"CLSID\\{586CDC7B-09F1-4f44-A110-F0E604AED81E}\\ProgID", 0, L"BeginningCOM.1"},
{L"BeginningCOM.1", 0, L"COM ProgID sample"},
{L"BeginningCOM.1\\CLSID", 0, L"{586CDC7B-09F1-4f44-A110-F0E604AED81E}"}
};
可以使用ProgIDFromCLSID函数,将CLSID转换为ProgID;使用CLSIDFromProgID将ProgID转换为CLSID,具体使用见MSDN。
COM有关的注册表内容:http://msdn.microsoft.com/en-us/library/ms678477(VS.85).aspx
源文件下载:BeginningCOM3.zip
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?