运行时加载程序集引发清单不匹配异常,求解决思路
解决思路
1. 修正AssemblyResolve回调逻辑
当前回调不管要解析的是哪个程序集,都固定返回Siemens.Engineering.dll,这是核心问题。当CLR尝试解析主程序集的依赖(比如Siemens.Engineering.Contract)时,错误的DLL返回直接导致版本不匹配异常。
修改回调,根据ResolveEventArgs.Name动态匹配需要加载的程序集:
private static Assembly MyResolver(object sender, ResolveEventArgs args) { // 从请求的程序集全名中提取短名称(剔除版本、公钥等后缀) var assemblyShortName = new AssemblyName(args.Name).Name; // 目标程序集所在的根目录 var assemblyRootDir = @"C:\Program Files\Siemens\Automation\Portal V18\PublicAPI\V18"; // 拼接对应DLL的完整路径 var targetAssemblyPath = Path.Combine(assemblyRootDir, $"{assemblyShortName}.dll"); if (File.Exists(targetAssemblyPath)) { return Assembly.LoadFrom(targetAssemblyPath); } // 找不到时返回null,让CLR继续尝试默认解析逻辑 return null; }
2. 验证依赖程序集版本一致性
检查以下两点:
- 项目中引用的
Siemens.Engineering.Contract版本,是否和目标目录中Siemens.Engineering.Contract.dll的实际版本完全匹配。可通过ILSpy、Reflector等工具查看DLL的清单版本信息。 - 如果目标目录的版本与项目引用版本不一致但确认兼容,可调整项目引用版本为目标目录的版本,或在回调中强制加载该版本(需承担兼容性风险)。
3. 提前预加载依赖程序集(可选)
若不想依赖AssemblyResolve事件自动触发,可在程序启动时提前加载所有必需的依赖:
static void Main(string[] args) { var assemblyRootDir = @"C:\Program Files\Siemens\Automation\Portal V18\PublicAPI\V18"; // 预加载主程序集和核心依赖 Assembly.LoadFrom(Path.Combine(assemblyRootDir, "Siemens.Engineering.dll")); Assembly.LoadFrom(Path.Combine(assemblyRootDir, "Siemens.Engineering.Contract.dll")); AppDomain.CurrentDomain.AssemblyResolve += MyResolver; doStuff(); }
4. 排查程序集加载上下文问题
Assembly.LoadFrom会将程序集加载到特定的加载上下文,部分场景下可能导致CLR版本匹配逻辑异常。若上述方法无效,可尝试改用Assembly.LoadFile加载(注意:LoadFile不会自动处理依赖,需手动加载所有关联DLL)。
内容的提问来源于stack exchange,提问作者Rodrigo Ferreira
相关产品推荐
相关产品推荐

