如何让FusionLoader从非AppBase路径加载XML Serializer程序集?
解决XML序列化程序集跨目录加载问题
问题概述
主程序Application.exe运行于C:\App\Bin目录,从C:\App\COMDLL加载C# COM组件。该COM组件依赖的COMDLL.XmlSerializers.dll已通过sgen.exe生成并存放于C:\App\COMDLL,但Fusion加载器始终仅在AppBase(C:\App\Bin)目录查找该序列化程序集。无法将序列化程序集移至AppBase目录,也无法修改Application.exe代码,仅能修改COMDLL项目。此前尝试的AssemblyResolve事件处理未生效,probing配置因目标路径非AppBase子目录无法使用。
可行解决方案
方案1:修正AssemblyResolve事件实现
原事件处理存在两处错误:返回类型不符合要求、程序集加载方式错误,修正后即可生效:
public static void RedirectDependency() { // 避免重复注册事件 if (!LibLoaded) { AppDomain.CurrentDomain.AssemblyResolve += ResolveHandler; LibLoaded = true; } } private static bool LibLoaded = false; // 返回类型改为Assembly,符合事件委托要求 public static Assembly ResolveHandler(object sender, ResolveEventArgs args) { var libName = new AssemblyName(args.Name); // 忽略大小写匹配序列化程序集名称 if (libName.Name.EndsWith("XmlSerializers", StringComparison.OrdinalIgnoreCase)) { var libPath = @"C:\App\COMDLL\COMDLL.XmlSerializers.dll"; if (File.Exists(libPath)) { // 使用LoadFrom加载指定路径的程序集 return Assembly.LoadFrom(libPath); } } return null; }
注意:需在COM组件的初始化阶段调用RedirectDependency,例如在COM类的静态构造函数中:
[ComVisible(true)] public class YourComImplementation { static YourComImplementation() { RedirectDependency(); } // 你的COM方法定义... }
方案2:使用codeBase配置元素
若允许创建或修改Application.exe.config,可添加codeBase元素直接指定序列化程序集的物理路径:
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="COMDLL.XmlSerializers" publicKeyToken="替换为你的程序集公钥令牌" culture="neutral" /> <codeBase version="替换为你的程序集版本号" href="file:///C:/App/COMDLL/COMDLL.XmlSerializers.dll" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
可通过ildasm.exe打开COMDLL.XmlSerializers.dll查看公钥令牌和版本号。
方案3:预加载序列化程序集
在COM组件初始化时直接加载序列化程序集,提前将其载入当前AppDomain,避免后续Fusion加载器的查找操作:
[ComVisible(true)] public class YourComImplementation { static YourComImplementation() { var serializerPath = @"C:\App\COMDLL\COMDLL.XmlSerializers.dll"; if (File.Exists(serializerPath)) { Assembly.LoadFrom(serializerPath); } } // 你的COM方法定义... }
方案选择建议
- 方案1是最通用的解决方案,只要事件注册成功即可拦截所有序列化程序集的解析请求,不受配置权限限制
- 方案2操作最简单,但需要具备修改主程序配置文件的权限
- 方案3适合序列化程序集路径固定、版本稳定的场景,实现成本低
内容的提问来源于stack exchange,提问作者user3017167
相关产品推荐
相关产品推荐

