如何(如果有的话)在 .NET 框架项目中使用 DinkToPdf nuget

How (if at all) to use DinkToPdf nuget in a .NET framework project

我有一个 .Net Framework 4.8 应用程序,我需要在其中将一些 html/css 转换为 pdf。

我采样了一个 DinkToPdf 的演示项目,它是“.NET Core P/Invoke wkhtmltopdf 库的包装器,它使用 Webkit 引擎将 HTML 页面转换为 PDF”。这适用于 .NET 核心应用程序和 Xamarin Forms 应用程序,但无法使其在 .Net Framewrk 应用程序中运行。

我已通过 NugetPackageManager 将 DinkToPDF v1.0.8 添加到我的项目的引用文件夹中。我查看了包依赖关系并确保所有包都符合要求的版本。 有一个本机库,我需要将其复制到我的项目根目录,因为 DinkToPdf 使用它:libwkhtmltox.dll(我尝试过不同版本) 我也试过 RndUsr0.DinkToPdf 包,"Upgraded to .NET Standard 2.0, .NET Core 2.1, wkhtmltopdf v0.12.5." 但没有更好的结果。

发生了什么:当我的应用程序调用 basicConverter.Converet(HtmlToPdfDocument doc) 时出现异常:"DinkToPdf.WkHtmlToXBindings::wkhtmltopdf_init' 使堆栈失衡。这可能是因为托管 PInvoke 签名与非托管目标签名不匹配。请检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。 “

    public static void ConvertToPdf(/*string [] args*/)
    {
        //load native lib libwkhtmltox.dll
        var architectureFolder = (IntPtr.Size == 8) ? "64 bit" : "32 bit";
        var wkHtmlToPdfPath = Path.Combine(AppContext.BaseDirectory, $"wkhtmltox\v0.12.4\{architectureFolder}\libwkhtmltox.dll");//here a libwkhtmltox.dll needs to be stored 
        IntPtr pDll = NativeMethods.LoadLibrary(wkHtmlToPdfPath);
        if (pDll == IntPtr.Zero)
        {
            throw new FileNotFoundException("-- Cannot load libwkhtmltox == a dll used for html to pdf convertion --");
        }
        var converter = new BasicConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            }
        };
        ObjectSettings objectSettings = new ObjectSettings()
        {
            PagesCount = true,
            HtmlContent = html,
            WebSettings = { DefaultEncoding = "utf-8"}
        };
        doc.Objects.Add(objectSettings);
        byte[] pdf = converter.Convert(doc);//!!! THIS IS THE POINT THAT THROWS UP
        string outputFile = Path.Combine(AppContext.BaseDirectory, "ImageFromHtmnl.pdf");
        using (FileStream stream = new FileStream(outputFile, FileMode.Create))
        {
            stream.Write(pdf, 0, pdf.Length);
        }
    }

总而言之:我希望带有 libwkhtmltox.dll 本机库的 DinkToPdf nuget 包在 .NET Framework 应用程序中运行,就像它在 .NET Core 应用程序中运行一样。但事实并非如此。

我错过了什么?

编辑: 忘记 post 这个 class 实现对本机库的调用。:

static class NativeMethods
{
    [DllImport("kernel32.dll"/*, CallingConvention = CallingConvention.Cdecl*/)]
    public static extern IntPtr LoadLibrary(string dllToLoad);

    [DllImport("kernel32.dll")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);


    [DllImport("kernel32.dll")]
    public static extern bool FreeLibrary(IntPtr hModule);

    public static string GetLibraryPathname(string filename)
    {
        // If 64-bit process, load 64-bit DLL
        bool is64bit = System.Environment.Is64BitProcess;

        string prefix = "Win32";

        if (is64bit)
        {
            prefix = "x64";
        }

        var lib1 = prefix + @"\" + filename;

        return lib1;
    }
}

我遇到了core/standard/framework/xamarin

解释得很好:

What is the Problem? Example: Let assume we create an application using .Net Framework and use its library for shared code. After some time, we feel to create an application in .Net Core and try to re-use the same shared code library which is created in .Net Framework. Can we do that? The answer is NO. We cannot use .Net Framework Base Class Library in .Net Core because of compatibility issues. Basically, the libraries which target to .Net Framework can only run in .Net Framework based application and the libraries which target to .Net Core can only run in .Net Core compatible applications. What is the Solution? The solution is .Net Standard. .Net Standard is a specification of the set of APIs which is compatible for any .Net platforms either it is .Net Framework or .Net Core. If we create the Base Class Library using .Net Standard, then it will run with any .Net Runtimes.