【问题标题】:Unable to load External library "libwkhtmltox.dll" while using DinkToPDF for PDF conversion after publishing as app service in azure在 azure 中发布为应用服务后,使用 DinkToPDF 进行 PDF 转换时无法加载外部库“libwkhtmltox.dll”
【发布时间】:2019-10-24 22:01:14
【问题描述】:

我正在使用 DinkToPDF 库将 html 字符串转换为等效的 PDF。 要使用这个库,我们必须导入提供的本地库 libwkhtmltox.dll。当我在本地运行我的 .net 核心项目时,这工作正常,但是当我尝试在 Azure 中将我的 Web 项目作为应用服务发布时,我收到以下错误,

未处理的异常:System.DllNotFoundException:无法加载共享库“/home/site/wwwroot/libwkhtmltox.dll”或其依赖项之一。为了帮助诊断加载问题,考虑设置 LD_DEBUG 环境变量:/home/site/wwwroot/libwkhtmltox.dll: cannot open shared object file: No such file or directory

我在下面的 startup.cs 文件中引用了库的使用情况。

    internal class CustomAssemblyLoadContext : AssemblyLoadContext
    {
        public IntPtr LoadUnmanagedLibrary(string absolutePath)
        {
            return LoadUnmanagedDll(absolutePath);
        }
        protected override IntPtr LoadUnmanagedDll(String unmanagedDllName)
        {
            return LoadUnmanagedDllFromPath(unmanagedDllName);
        }

        protected override Assembly Load(AssemblyName assemblyName)
        {
            throw new NotImplementedException();
        }
    }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
            var context = new CustomAssemblyLoadContext();
            context.LoadUnmanagedLibrary(Path.Combine(Directory.GetCurrentDirectory(), "libwkhtmltox.dll"));
         .
         .
         .
        }

请帮我找出这个错误的解决方案。

【问题讨论】:

  • 你如何解决这个问题?可以更新吗?

标签: azure .net-core dinktopdf


【解决方案1】:

你需要设置库的绝对路径,对于windows不需要使用“.dll”,在我的例子中它被放置在[project_root]/wkhtmltox/v0.12.4/[x_64|x_86]

var architectureFolder = (IntPtr.Size == 8) ? "x_64" : "x_86";
var wkHtmlToPdfFileName = "libwkhtmltox";
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
    wkHtmlToPdfFileName += ".so";
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
    wkHtmlToPdfFileName += ".dylib";
}

var wkHtmlToPdfPath = Path.Combine(
    new string[] {
        _hostingEnvironment.ContentRootPath,
        "wkhtmltox",
        "v0.12.4",
        architectureFolder,
        wkHtmlToPdfFileName
    });

CustomAssemblyLoadContext context = new CustomAssemblyLoadContext();
context.LoadUnmanagedLibrary(wkHtmlToPdfPath);
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

【讨论】:

    【解决方案2】:

    您必须将 dll 扩展名复制到项目的根目录

    之后你必须创建一个内部类来加载 dll

    将此添加到您的课程中

    using System.Runtime.Loader;
    using System.Reflection;
    

    要包括的方法:

        internal class CustomAssemblyLoadContext : AssemblyLoadContext
        {
            public IntPtr LoadUnmanagedLibrary(string absolutePath)
            {
                return LoadUnmanagedDll(absolutePath);
            }
            protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
            {
                return LoadUnmanagedDllFromPath(unmanagedDllName);
            }
    
            protected override Assembly Load(AssemblyName assemblyName)
            {
                throw new NotImplementedException();
            }
        }
    

    【讨论】:

      【解决方案3】:

      在 dockerfile 中将以下命令插入到组件引擎 html 到 pdf 中:

      FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
      
      RUN apt-get update
      
      RUN apt-get install -y apt-utils
      
      RUN apt-get install -y libgdiplus
      
      RUN apt-get install -y libc6-dev
       
      RUN ln -s /usr/lib/libgdiplus.so/usr/lib/gdiplus.dll
      

      【讨论】:

        【解决方案4】:

        试试这个: 从https://github.com/rdvojmoc/DinkToPdf/tree/master/v0.12.4下载包

        通过自定义程序集引用将其添加到您的项目引用并在您的启动项目中注册。 这是自定义程序集加载上下文,可以从绝对路径加载库。

        internal class CustomAssemblyLoadContext : AssemblyLoadContext
        {
            public IntPtr LoadUnmanagedLibrary(string absolutePath)
            {
                return LoadUnmanagedDll(absolutePath);
            }
            protected override IntPtr LoadUnmanagedDll(String unmanagedDllName)
            {
                return LoadUnmanagedDllFromPath(unmanagedDllName);
            }
        
            protected override Assembly Load(AssemblyName assemblyName)
            {
                throw new NotImplementedException();
            }
        }

        在 Statup.cs 添加以下代码。 在创建转换器之前调用 CustomAssemblyLoadContext:

        CustomAssemblyLoadContext 上下文 = new CustomAssemblyLoadContext(); context.LoadUnmanagedLibrary(path);

        var 转换器 = new SynchronizedConverter(new PdfTools()); services.AddSingleton(转换器); services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

        【讨论】:

          猜你喜欢
          • 2019-11-07
          • 2018-11-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-12-10
          • 1970-01-01
          相关资源
          最近更新 更多