C# LocalReport如何加载非程序根目录下的自定义程序集?
RDLC报表自定义程序集子目录加载失败的解决办法
问题场景
基于.NET Framework 4.8的应用中,使用LocalReport渲染RDLC报表,报表引用了子目录下的自定义程序集,通过AddFullTrustModuleInSandboxAppDomain添加强命名程序集后,仅当程序集在应用根目录时能正常加载,放在子目录则抛出程序集找不到的异常。
可行解决方案
方案1:注册沙箱AppDomain的程序集解析事件
LocalReport运行在独立的沙箱AppDomain中,可通过注册该域的AssemblyResolve事件,手动从指定子目录加载程序集:
// 定义自定义程序集所在的子目录路径 string customAssemblyDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CustomAssemblies"); // 获取LocalReport的沙箱AppDomain实例 AppDomain sandboxDomain = localReport.GetSandboxAppDomain(); // 注册程序集解析事件,按需加载子目录中的程序集 sandboxDomain.AssemblyResolve += (sender, resolveArgs) => { var targetAssemblyName = new AssemblyName(resolveArgs.Name); string assemblyFilePath = Path.Combine(customAssemblyDir, $"{targetAssemblyName.Name}.dll"); if (File.Exists(assemblyFilePath)) { // 从指定路径加载程序集 return Assembly.LoadFrom(assemblyFilePath); } // 找不到则返回null,继续默认搜索逻辑 return null; }; // 后续执行添加强命名程序集和报表渲染逻辑 var assemblyName = customAssembly.GetName(); var strongAssemblyName = new StrongName(new StrongNamePublicKeyBlob(assemblyName.GetPublicKeyToken()), assemblyName.Name, assemblyName.Version); localReport.AddFullTrustModuleInSandboxAppDomain(strongAssemblyName);
方案2:通过配置文件添加程序集搜索路径
修改应用的App.config,添加probing节点指定私有搜索路径,CLR会自动在这些子目录中查找程序集:
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <!-- 逗号分隔多个子目录路径 --> <probing privatePath="CustomAssemblies;ReportAssemblies" /> </assemblyBinding> </runtime> </configuration>
此方案无需修改代码,只需确保自定义程序集已强命名并通过AddFullTrustModuleInSandboxAppDomain添加到沙箱域即可。
方案3:预加载子目录程序集后添加信任
先从子目录加载目标程序集,再提取其强命名信息添加到沙箱域的信任列表:
// 指定子目录中的程序集路径 string assemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CustomAssemblies", "MyCustomAssembly.dll"); // 从子目录加载程序集 Assembly customAssembly = Assembly.LoadFrom(assemblyPath); // 提取强命名信息并添加到沙箱域信任列表 var assemblyName = customAssembly.GetName(); var strongAssemblyName = new StrongName(new StrongNamePublicKeyBlob(assemblyName.GetPublicKeyToken()), assemblyName.Name, assemblyName.Version); localReport.AddFullTrustModuleInSandboxAppDomain(strongAssemblyName);
注意事项
- 所有自定义程序集必须是强命名的,否则无法通过
AddFullTrustModuleInSandboxAppDomain添加信任。 - 确保沙箱AppDomain拥有访问子目录的权限,避免因权限不足导致加载失败。
- 若使用方案1,需确保在报表渲染前注册
AssemblyResolve事件,且事件处理逻辑中做好文件存在性校验。
内容的提问来源于stack exchange,提问作者Master_T
相关产品推荐
相关产品推荐

