You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 03:43:22