如何获取已引用的interop互操作程序集中的所有类型
问题根因
1. 核心原因:嵌入互操作类型特性
你遇到的类型所属程序集识别错误的现象,是COM引用的默认配置「嵌入互操作类型」导致的:
编译器会将你代码中用到的COM类型定义直接嵌入到当前项目生成的程序集(也就是你这里的MyApp)中,不会完整引用原始Interop dll,也不会将Interop dll作为依赖项加载到应用域中。
因此你通过typeof(Component2).Assembly拿到的自然是你自己的程序集,常规反射方法也检索不到原始的Interop程序集。
2. 加载报错的额外原因
你测试代码中Assembly.Load(assemblyNameOfClassInDLL)抛出异常属于调用错误:Load方法要求传入的是程序集名称,但你传入的是类型的程序集限定名(包含了类型名、命名空间字段),自然会触发程序集名称无效的报错。
解决方案
完全可以满足你给出的两个要求,提供两种适配不同场景的方案:
方案1:修改引用配置(最简单,无额外编码)
如果可以调整项目引用属性,直接修改COM引用的配置即可让原有反射逻辑正常生效:
- 在项目的引用列表中找到对应COM引用(如SldWorks),右键打开属性面板
- 将「嵌入互操作类型」设置为
False,「复制本地」设置为True - 重新编译项目后,所有COM类型都会归属于原始Interop程序集,直接调用
typeof(Component2).Assembly.GetTypes()就能拿到该程序集下的全部类型。
方案2:不修改现有引用,手动加载原始Interop程序集(适配动态插件场景)
如果你是动态加载的插件,不方便修改引用配置,可以直接从原始Interop dll加载并读取类型:
步骤1:拿到目标COM类型的CLSID
COM类型都自带Guid特性,你可以直接从已有的类型定义读取,不需要依赖所属程序集:
var targetComType = typeof(Component2); // 拿到带大括号格式的CLSID string clsid = targetComType.GUID.ToString("B");
步骤2:加载原始Interop程序集
如果你的部署环境中Interop dll路径固定,直接从文件加载即可:
// 替换为你实际的Interop dll存放路径 string interopDllPath = @"C:\部署路径\Interop.SldWorks.dll"; Assembly interopAssembly = Assembly.LoadFrom(interopDllPath); // 获取该Interop程序集下的所有类型 Type[] allTypesInInterop = interopAssembly.GetTypes();
如果需要动态定位Interop dll路径,可以从系统注册表读取:COM类的CLSID在HKEY_CLASSES_ROOT\CLSID\{你拿到的CLSID}\InprocServer32路径下存储了对应程序集的物理路径,读取该注册表值即可拿到动态路径。
内容的提问来源于stack exchange,提问作者Franck
相关产品推荐
相关产品推荐

