.NET Core应用加载PDFSharp程序集时丢失.dll扩展名问题排查
问题详情
我的ASP.NET Core应用引用了PDFSharp 6.0.0包,该包包含6个DLL文件:
- PdfSharp.Charting.dll
- PdfSharp.dll
- PdfSharp.Quality.dll
- PdfSharp.Snippets.dll
- PdfSharp.System.dll
- PdfSharp.WPFonts.dll
应用编译运行正常,但调用PDFSharp相关代码时抛出错误:
未能加载文件或程序集“PdfSharp.System, Version=6.0.0.0, Culture=neutral, PublicKeyToken=null”。系统找不到指定的文件。
通过Process Monitor观察到:程序成功加载了PdfSharp.dll,但加载PdfSharp.System时提示“NAME NOT FOUND”——明显没有自动追加.dll扩展名。将PdfSharp.System.dll重命名为PdfSharp.System后可以正常加载,但这并非合理解决方案。
已尝试的无效操作
原本的.csproj配置:
<ItemGroup> <PackageReference Include="PDFsharp" Version="6.0.0" /> </ItemGroup>
尝试添加手动引用后无效果,Process Monitor仍未尝试加载带.dll扩展名的文件:
<ItemGroup> <PackageReference Include="PDFsharp" Version="6.0.0" /> <Reference Include="PDFsharp.System"> <HintPath>\.PDFsharp.System.dll</HintPath> </Reference> </ItemGroup>
原因分析
这种情况大概率是PDFSharp包本身的程序集元数据问题:PdfSharp.System.dll的程序集内部名称被定义为PdfSharp.System(不带.dll后缀),导致CLR在加载时直接使用这个名称去查找文件,而非自动追加.dll扩展名。另外ASP.NET Core的依赖解析逻辑中,当包引用的程序集元数据与实际文件名不匹配时,也会出现这类加载异常。
解决方案
1. 指定目标运行时(优先推荐)
在.csproj中添加RuntimeIdentifier,确保NuGet正确复制对应运行时的DLL文件,避免依赖解析混乱:
<PropertyGroup> <!-- 根据实际运行环境选择,比如win-x86、linux-x64等 --> <RuntimeIdentifier>win-x64</RuntimeIdentifier> </PropertyGroup>
2. 强制复制缺失的DLL到输出目录
手动指定将PdfSharp.System.dll复制到输出目录,确保CLR能找到正确的文件:
<ItemGroup> <Content Include="$(NuGetPackageRoot)pdfsharp\6.0.0\lib\net6.0\PdfSharp.System.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <Link>PdfSharp.System.dll</Link> </Content> </ItemGroup>
注意:路径中的net6.0需匹配你的项目目标框架版本,比如net7.0、net8.0。
3. 手动处理程序集加载事件
在Program.cs中添加AssemblyResolve事件,当CLR找不到程序集时,自动尝试追加.dll扩展名查找:
using System.Reflection; using System.IO; var builder = WebApplication.CreateBuilder(args); // 添加程序集加载解析逻辑 AppDomain.CurrentDomain.AssemblyResolve += (sender, resolveArgs) => { var assemblyShortName = new AssemblyName(resolveArgs.Name).Name; var targetPath = Path.Combine(AppContext.BaseDirectory, $"{assemblyShortName}.dll"); return File.Exists(targetPath) ? Assembly.LoadFrom(targetPath) : null; }; // 其他项目配置... var app = builder.Build(); // 中间件配置... app.Run();
4. 检查并修复PDFSharp包(自行构建包时适用)
如果是自己构建的PDFSharp包,修改PdfSharp.System项目的程序集名称,确保和文件名一致(即设置为PdfSharp.System.dll),然后重新打包发布。
内容的提问来源于stack exchange,提问作者Ken

