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

如何将Pdfium等依赖DLL嵌入程序?Costura.Fody未生效问题

问题分析与解决方案

为什么Costura.Fody没生效?

Costura.Fody确实能自动打包托管DLL,但对于Pdfium.dll这种非托管原生DLL,需要额外配置才能正确处理,另外还有几个常见坑:

  • 你可能没在FodyWeavers.xml中明确指定要打包的非托管DLL,Costura默认不会自动识别所有非托管文件
  • Pdfium分x86/x64架构版本,如果你的项目没有针对特定架构编译,或者Costura没配置对应架构的DLL,打包后运行时会找不到匹配的版本
  • 若你是手动引用的PdfiumViewer.dll而非通过NuGet安装,Costura可能没正确识别到这个托管DLL的引用关系

解决方案

方案1:修复Costura.Fody的配置

这是最省心的方式,只要正确配置就能让Costura自动打包并加载这两个DLL:

  1. 确保安装了最新版的Costura.Fody NuGet包
  2. 在项目根目录创建或修改FodyWeavers.xml,添加非托管DLL的架构配置:
<Weavers>
  <Costura>
    <!-- 指定32位和64位的Pdfium.dll -->
    <Unmanaged32Assemblies>pdfium</Unmanaged32Assemblies>
    <Unmanaged64Assemblies>pdfium</Unmanaged64Assemblies>
    <!-- 托管的PdfiumViewer.dll会自动被打包,无需额外配置 -->
  </Costura>
</Weavers>
  1. 检查你的Pdfium.dll(分x86/x64版本)是否放在项目对应的架构目录下(比如x86和x64子文件夹),并且它们的复制到输出目录属性设置为始终复制
  2. 重新编译项目,现在Costura会把对应架构的Pdfium.dll和PdfiumViewer.dll都打包进exe,运行时自动加载

方案2:手动嵌入并提取DLL(不依赖Costura)

如果Costura还是不好用,可以手动控制DLL的嵌入和加载:

  1. 把Pdfium.dll(分x86/x64)和PdfiumViewer.dll添加到项目中,在属性里设置生成操作为嵌入的资源
  2. 在程序启动的Main方法中,先提取并加载非托管的Pdfium.dll,再处理托管的PdfiumViewer.dll:
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr LoadLibrary(string lpFileName);

    static void Main(string[] args)
    {
        // 判断当前进程架构,加载对应版本的Pdfium.dll
        var is64Bit = Environment.Is64BitProcess;
        var pdfiumResourceName = is64Bit 
            ? "YourProjectName.x64.pdfium.dll" 
            : "YourProjectName.x86.pdfium.dll";
        
        // 提取Pdfium.dll到临时目录
        var tempPdfiumPath = Path.Combine(Path.GetTempPath(), "pdfium.dll");
        using (var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(pdfiumResourceName))
        {
            if (resourceStream == null)
                throw new FileNotFoundException("未找到嵌入的Pdfium.dll资源", pdfiumResourceName);
            
            using (var fileStream = new FileStream(tempPdfiumPath, FileMode.Create, FileAccess.Write))
            {
                resourceStream.CopyTo(fileStream);
            }
        }

        // 加载Pdfium.dll
        LoadLibrary(tempPdfiumPath);

        // 加载托管的PdfiumViewer.dll(如果需要)
        var viewerResourceName = "YourProjectName.PdfiumViewer.dll";
        using (var viewerStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(viewerResourceName))
        {
            if (viewerStream == null)
                throw new FileNotFoundException("未找到嵌入的PdfiumViewer.dll资源", viewerResourceName);
            
            var viewerBytes = new byte[viewerStream.Length];
            viewerStream.Read(viewerBytes, 0, viewerBytes.Length);
            Assembly.Load(viewerBytes);
        }

        // 后续正常启动你的程序逻辑
    }
}

注意替换代码中的YourProjectName为你的实际项目名称,确保资源路径和嵌入的资源名称一致。

方案3:使用PdfiumViewer的官方NuGet包

如果你之前是手动引用的DLL,建议卸载手动引用,直接安装PdfiumViewer NuGet包——它会自动管理不同架构的Pdfium.dll,再配合Costura.Fody的配置,大概率能直接解决打包问题,无需手动处理架构和路径。

内容的提问来源于stack exchange,提问作者derekantrican

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:02:14