rdvojmoc / DinkToPdf

C# .NET Core wrapper for wkhtmltopdf library that uses Webkit engine to convert HTML pages to PDF.
MIT License
1.1k stars 416 forks source link

Use of Dinktopdf lib in .Net framework app unbalances the stack #92

Open fashrista opened 5 years ago

fashrista commented 5 years ago

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. This worked in .NET core app and in Xamarin Forms app (where I ocasionally get Memory accsess violation Exception), 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 shure 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()
    {
        //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);
        }
    }
 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;
        }
    }

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?

eislasq commented 2 months ago

Hi @fashrista have you found a solution to use DinkToPdf in .NET Framework 4.8?

fashrista commented 2 months ago

Hi @fashrista have you found a solution to use DinkToPdf in .NET Framework 4.8?

No. As far as I can recall we finally decided to use a different lib sharpPDF to create pdfs. I think it was in a Unity project so probably the migradoc plugin with .net2.0 wasu used. Just remember it was really basic and it was alot of work and hacky solutions to implement. But it got the job done.

eislasq commented 2 weeks ago

Nice! In my case, I decided to use OpenHtmlToPdf. I built all the content in HTML and then passed it to the library to generate the PDF. Cheers!