简体   繁体   中英

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

I have a .Net Framework 4.8 app and in it I need to convert some html/css into pdf.

I have sampled a demo project of DinkToPdf, which is ".NET Core P/Invoke wrapper for wkhtmltopdf library that uses Webkit engine to convert HTML pages to PDF". This worked in .NET core app and in Xamarin Forms app, but cannot get it to function in a .Net Framewrk app.

I have added DinkToPDF v1.0.8 to my project's reference folder via NugetPackageManager. I have looked into package dependencies and made sure that all are up to required versions. There is a native lib that I needed to copy to my projects root becouse the DinkToPdf uses it: libwkhtmltox.dll (I have tryed different versions of this) I have also tryed RndUsr0.DinkToPdf package, which "Upgraded to .NET Standard 2.0, .NET Core 2.1, wkhtmltopdf v0.12.5." but had no beter results.

What happens: When my app calls basicConverter.Converet(HtmlToPdfDocument doc)I get an Exception:"DinkToPdf.WkHtmlToXBindings::wkhtmltopdf_init' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.' "

    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);
        }
    }

To conclude: I would expect the DinkToPdf nuget package with libwkhtmltox.dll native lib to function in a .NET Framework app just as well as it functions in a .NET Core app. But it does not.

What have I missed?

EDIT: Forgot to post this class that implements the call to native lib.:

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;
    }
}

I came across core/standard/framework/xamarin

which explains nicely:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM