Delphi用mscorlib调用.NET类创建Assembly实例报类未注册如何解决
问题根因
直接调用CoAssembly.Create触发"类未注册"错误,本质是mscorlib.tlb里映射的_Assembly接口对应的托管Assembly类,没有做传统原生COM组件的注册表项注册。这类.NET托管类型的COM互操作是由CLR(.NET公共语言运行时)统一托管调度的,不支持直接通过标准COM的CoCreateInstance逻辑直接创建实例。
解决方案
方案1:手动承载CLR运行时获取实例(推荐,无注册表修改风险)
这是最稳定的实现方式,不需要修改系统注册表,也不会引发不同.NET版本的冲突,核心逻辑是先在Delphi进程里启动对应版本的CLR,再通过CLR提供的应用域接口加载程序集拿到_Assembly实例,核心代码参考:
uses mscorlib, mscoree; var hr: HRESULT; CLRMetaHost: ICLRMetaHost; CLRRuntimeInfo: ICLRRuntimeInfo; CLRRuntimeHost: ICLRRuntimeHost; DefaultDomain: _AppDomain; myAssembly: _Assembly; begin // 创建CLR元宿主实例 hr := CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, CLRMetaHost); if FAILED(hr) then Exit; // 匹配目标.NET Framework版本,此处以v4.0.30319为例,可按需替换为v2.0.50727等版本 hr := CLRMetaHost.GetRuntime(L'v4.0.30319', IID_ICLRRuntimeInfo, CLRRuntimeInfo); if FAILED(hr) then Exit; // 启动CLR运行时 hr := CLRRuntimeInfo.GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, CLRRuntimeHost); if FAILED(hr) then Exit; CLRRuntimeHost.Start; // 获取CLR默认应用域 DefaultDomain := CorDefaultDomain.GetDefaultDomain; // 加载目标程序集,可传入程序集全名、文件路径等参数 myAssembly := DefaultDomain.Load_2('mscorlib'); end.
方案2:注册mscorlib COM互操作项(不推荐)
如果必须沿用CoAssembly.Create的调用逻辑,可以手动注册mscorlib的COM互操作信息:
- 打开对应版本.NET Framework的开发人员命令提示符,注意匹配你的程序编译目标平台(x86/x64)选择对应32/64位版本的regasm工具
- 执行注册命令:
regasm C:\Windows\Microsoft.NET\Framework\对应版本号\mscorlib.dll /tlb /codebase
风险提示:mscorlib是.NET Framework核心系统程序集,手动注册COM项很容易引发系统上不同.NET版本、不同位数程序的互操作冲突,非特殊场景不建议使用该方案。
方案3:使用成熟的Delphi-.NET互操作封装
如果不想手动编写CLR承载逻辑,可以引入已经封装完成的互操作单元,这类封装已经处理了CLR版本匹配、运行时启动、接口映射的全部逻辑,不需要额外注册组件,直接调用封装好的程序集加载方法即可拿到_Assembly接口实例。
内容的提问来源于stack exchange,提问作者ohr93
相关产品推荐
相关产品推荐

