我有一个.Net框架4.8应用程序,在其中,我需要将一些html/css转换成pdf。
我已经尝试了DinkToPdf的一个演示项目,它是".NET Core /Invoke包装器for wkhtmltopdf库,它使用Webkit引擎将HTML转换为PDF“。这在.NET核心应用程序和Xamarin Forms应用程序中都有效,但无法在.Net Framewrk应用程序中发挥作用。
我通过DinkToPDF将NugetPackageManager v1.0.8添加到项目的参考文件夹中。我研究了包的依赖关系,并确保所有的版本都符合所需的版本。我需要将一个本机库复制到我的项目根目录中,因为DinkToPdf使用它: libwkhtmltox.dll (我尝试过不同的版本),我也尝试过RndUsr0.DToPdf包,它“升级到.NET标准2.0、.NET Core2.1、wkhtmltopdfv0.12.5”。但没有更好的结果。
发生什么情况:当我的应用程序调用basicConverter.Converet(HtmlToPdfDocument文档)时,我得到了一个不平衡的堆栈。这很可能是因为托管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);
}
}
最后,我希望带有DinkToPdf本机库的libwkhtmltox.dll nuget包能够在.NET框架应用程序中运行,就像它在.NET核心应用程序中的功能一样。但事实并非如此。
我错过了什么?
编辑:忘记发布这个类来实现对本机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;
}
}
发布于 2019-09-17 09:45:27
我偶然发现了核心/标准/框架/
这很好地解释了:
有什么问题吗?示例:假设我们使用.Net框架创建了一个应用程序,并将其库用于共享代码。过了一段时间,我们觉得应该在.Net核心中创建一个应用程序,并尝试重用在.Net框架中创建的相同的共享代码库。我们能这么做吗?答案是否定的。由于兼容性问题,我们不能在.Net核心中使用.Net框架基类库。基本上,针对.Net框架的库只能在基于.Net框架的应用程序中运行,而针对.Net核心的库只能在.Net兼容的应用程序中运行。解决方案是什么?解决方案是.Net标准。.Net标准是一组API的规范,它兼容于任何.Net平台,无论是.Net框架还是.Net核心。如果我们使用.Net标准创建基类库,那么它将与任何.Net运行时一起运行。
https://stackoverflow.com/questions/57887604
复制相似问题