跳過到頁腳內容
遷移指南

從 Haukcode.DinkToPdf 遷移到 IronPDF

從 Haukcode.DinkToPdf 移植到 IronPDF:完整的 C# 開發人員指南。

Haukcode.DinkToPdf 是之前廣受歡迎的 DinkToPdf 函式庫的分叉,它包覆了 wkhtmltopdf 二進位檔,為 .NET 應用程式提供 HTML 至 PDF 的轉換功能。 在原始 DinkToPdf 專案停滯不前後,Haukcode.DinkToPdf 雖維持與 .NET Core 的相容性,但卻繼承了其上游相依性的重要安全漏洞。 底層的 wkhtmltopdf 專案已於 2023 年 1 月歸檔,這意味著這些漏洞將永遠無法修補。

本指南提供了從 Haukcode.DinkToPdf 到IronPDF的完整遷移路徑,其中包含分步說明、程式碼比較以及實用範例,適合需要從 PDF 生成工作流程中消除安全風險的專業 .NET 開發人員使用。

重要安全警告:CVE-2022-35583

Haukcode.DinkToPdf 從 wkhtmltopdf 繼承了一個無法修復的重要安全漏洞:

CVE-2022-35583 - 關鍵 SSRF 漏洞 (CVSS 9.8)

wkhtmltopdf 函式庫(以及包括 Haukcode.DinkToPdf 在內的所有包裝程式)容易受到伺服器端請求偽造 (SSRF) 的攻擊:

  • 攻擊向量:惡意的 HTML 內容可使伺服器取得內部資源
  • AWS 元資料攻擊:可存取 http://169.254.169.254 以竊取 AWS 認證
  • 內部網路存取:可掃描及存取內部服務
  • 包含本機檔案:可透過 file:// 通訊協定讀取本機檔案
  • 影響:可能完全接管基礎架構

此漏洞沒有修復程式,因為 wkhtmltopdf 已於 2023 年廢棄並歸檔。最後發行的版本是 2020 年的 0.12.6 版。

IronPDFvs Haukcode.DinkToPdf:功能比較

了解架構上的差異有助於技術決策者評估遷移投資:

範疇Haukcode.DinkToPdfIronPDF
基礎引擎wkhtmltopdf (Qt WebKit ~2015)Chromium (定期更新)
安全狀態CVE-2022-35583 (CRITICAL, unfixable)積極修補
專案狀態廢棄專案的分叉積極開發
HTML5/CSS3限額全面支援
JavaScript有限、不安全完整的 V8 引擎
原生二進位必需(特定平台)自成一格
線程安全需要單元模式線程安全的設計
<強>支援</強僅限社群專業支援
更新無預期定期發佈
執照MIT (免費)免費試用的商業版

快速入門:Haukcode.DinkToPdf 到IronPDF的遷移。

只要完成這些基本步驟,就可以立即開始遷移。

步驟 1:移除 DinkToPdf 和原生二進位檔案

移除 Haukcode.DinkToPdf NuGet 套件:

# Remove NuGet packages
dotnet remove package DinkToPdf
dotnet remove package Haukcode.DinkToPdf
dotnet remove package Haukcode.WkHtmlToPdf-DotNet
# Remove NuGet packages
dotnet remove package DinkToPdf
dotnet remove package Haukcode.DinkToPdf
dotnet remove package Haukcode.WkHtmlToPdf-DotNet
SHELL

從專案中刪除原生二進檔:

  • libwkhtmltox.dll (Windows)
  • libwkhtmltox.so (Linux)
  • libwkhtmltox.dylib (macOS)

步驟 2:安裝 IronPDF

# Install IronPDF
dotnet add package IronPdf
# Install IronPDF
dotnet add package IronPdf
SHELL

步驟 3:更新命名空間

用 IronPdf 取代 DinkToPdf 命名空間:

// Before (Haukcode.DinkToPdf)
using DinkToPdf;
using DinkToPdf.Contracts;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;  // For RenderingOptions
// Before (Haukcode.DinkToPdf)
using DinkToPdf;
using DinkToPdf.Contracts;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;  // For RenderingOptions
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

步驟 4:初始化授權

在應用程式啟動時加入授權初始化:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

程式碼遷移範例

基本 HTML 到 PDF 的轉換

最基本的操作揭示了這些 .NET PDF 函式庫的複雜性差異。

Haukcode.DinkToPdf 方法:

// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());

        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<html><body><h1>Hello World</h1></body></html>",
                }
            }
        };

        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());

        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<html><body><h1>Hello World</h1></body></html>",
                }
            }
        };

        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

IronPDF 方法:

// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Hello World</h1></body></html>");

        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Hello World</h1></body></html>");

        pdf.SaveAs("output.pdf");
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf 要求使用<編碼>PdfTools</編碼創建一個 SynchronizedConverter, 用嵌套的全局設定Objects 建構一個 HtmlToPdfDocument, 加入一個物件設定HtmlContent, 呼叫 converter.Convert()來取得原始位元組,並使用 File.WriteAllBytes() 來手動寫入檔案。

IronPDF 將此簡化為三行:建立 ChromePdfRenderer, 呼叫 RenderHtmlAsPdf(), 並使用內建的 SaveAs() 方法。

如需進階的 HTML 至IronPDF情境,請參閱 HTML 至 PDF 轉換指南

將 URL 轉換為 PDF

URL 到 PDF 的轉換也顯示出類似的模式差異。

Haukcode.DinkToPdf 方法:

// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());

        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            },
            Objects = {
                new ObjectSettings() {
                    Page = "https://www.example.com",
                }
            }
        };

        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());

        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4,
            },
            Objects = {
                new ObjectSettings() {
                    Page = "https://www.example.com",
                }
            }
        };

        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

IronPDF 方法:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");

        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");

        pdf.SaveAs("webpage.pdf");
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf 使用與 ObjectSettings.Page 相同的文件建構模式來處理 URL。IronPDF提供了一個專用的 RenderUrlAsPdf() 方法,可以清楚地表達出意圖。

探索URL至PDF文件的認證和自訂標頭選項。

自訂頁面設定

配置方向、紙張大小和頁邊需要不同的方法。

Haukcode.DinkToPdf 方法:

// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());

        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Landscape,
                PaperSize = PaperKind.Letter,
                Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>",
                }
            }
        };

        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("landscape.pdf", pdf);
    }
}
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());

        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Landscape,
                PaperSize = PaperKind.Letter,
                Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>",
                }
            }
        };

        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("landscape.pdf", pdf);
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

IronPDF 方法:

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;

        var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>");

        pdf.SaveAs("landscape.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;

        var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>");

        pdf.SaveAs("landscape.pdf");
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf 將設定嵌套在全局設定與一個獨立的 MarginSettings 物件內。IronPDF提供直接的渲染選項屬性,這些屬性具有清晰的名稱,例如 PaperSize, PaperOrientation 以及個別的邊界屬性。

Haukcode.DinkToPdf API 到IronPDF的映射參考。

此對應可透過顯示直接的 API 對應關係來加速遷移:

轉換器類別對應

Haukcode.DinkToPdfIronPDF筆記
同步轉換器<代碼>ChromePdfRenderer</代碼線程安全,無需單元
基本轉換器<代碼>ChromePdfRenderer</代碼相同的類別處理兩者
<編碼>PdfTools</編碼不適用不需要
IConverter不適用直接使用渲染器

文件配置映射

Haukcode.DinkToPdfIronPDF筆記
<編碼>HtmlToPdfDocument</編碼方法調用直接使用 RenderHtmlAsPdf()
全局設定渲染選項渲染前設定
物件設定渲染選項合併為一個
converter.Convert(doc)renderer.RenderHtmlAsPdf(html)返回 PdfDocument

GlobalSettings 屬性對應

GlobalSettings 屬性IronPdf 特性筆記
<編碼>ColorMode</編碼RenderingOptions.GrayScale布林,設定 true 為灰階
<編碼>方向</編碼<編碼>RenderingOptions.PaperOrientation</編碼肖像風景
紙張大小RenderingOptions.PaperSize使用 PdfPaperSize 枚舉
Margins.TopRenderingOptions.MarginTop以毫米為單位
邊界.底部RenderingOptions.MarginBottom以毫米為單位
Margins.LeftRenderingOptions.MarginLeft以毫米為單位
Margins.Right<編碼>RenderingOptions.MarginRight</編碼以毫米為單位

物件設定屬性對應

物件設定屬性IronPdf 同等級產品筆記
<編碼>Html內容</編碼RenderHtmlAsPdf() 的第一個參數直接參數
頁面 (URL)renderer.RenderUrlAsPdf(url)獨立方法
HeaderSettings.Right = "[page]"TextHeader.RightText="{page}"不同的占位符語法

占位符語法遷移

Haukcode.DinkToPdfIronPDF筆記
[page]{page}目前頁數
[toPage]{總頁數}總頁數
[日期]<編碼>{日期}</編碼目前日期

常見的遷移問題與解決方案

問題 1:單元需求

Haukcode.DinkToPdf: 由於本機 wkhtmltopdf 二進位的線程安全問題,因此需要同步轉換器作為單例。

解決方案:IronPDF的<代碼>ChromePdfRenderer</代碼在設計上是線程安全的 - 不需要單例:

// Before (DinkToPdf) - MUST be singleton
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

// After (IronPDF) - Can be singleton or transient (both work)
services.AddSingleton<IPdfService, IronPdfService>();
// Or services.AddTransient<IPdfService, IronPdfService>() - both are safe!
// Before (DinkToPdf) - MUST be singleton
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

// After (IronPDF) - Can be singleton or transient (both work)
services.AddSingleton<IPdfService, IronPdfService>();
// Or services.AddTransient<IPdfService, IronPdfService>() - both are safe!
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

問題 2:原生二進位相依性

Haukcode.DinkToPdf:需要特定平台的本機庫 (libwkhtmltox.dll/so/dylib)。

解決方案:IronPDF是獨立的,沒有本機的二進位相依性。 遷移後刪除這些檔案:

  • libwkhtmltox.dll (Windows)
  • libwkhtmltox.so (Linux)
  • libwkhtmltox.dylib (macOS)

問題 3:回傳類型的差異

Haukcode.DinkToPdf:converter.Convert()直接返回byte[]

解決方案:IronPDF會返回一個具有多種輸出選項的 PdfDocument 物件:

var pdf = renderer.RenderHtmlAsPdf(html);
byte[] bytes = pdf.BinaryData;  // Get bytes
pdf.SaveAs("output.pdf");       // Or save directly
var pdf = renderer.RenderHtmlAsPdf(html);
byte[] bytes = pdf.BinaryData;  // Get bytes
pdf.SaveAs("output.pdf");       // Or save directly
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

問題 4:頁首/頁尾占位符語法

Haukcode.DinkToPdf:使用方括號語法,如[page][toPage]

解決方案:更新IronPDF的大括弧占位符:

// Before (DinkToPdf)
HeaderSettings = { Right = "Page [page] of [toPage]" }

// After (IronPDF)
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
    RightText = "Page {page} of {total-pages}"
};
// Before (DinkToPdf)
HeaderSettings = { Right = "Page [page] of [toPage]" }

// After (IronPDF)
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
    RightText = "Page {page} of {total-pages}"
};
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf 移轉清單

遷移前的任務

審核您的程式碼庫,找出所有 DinkToPdf 的使用情況:

# Find DinkToPdf namespace usage
grep -r "using DinkToPdf\|using Haukcode" --include="*.cs" .

# Find converter usage
grep -r "SynchronizedConverter\|BasicConverter\|HtmlToPdfDocument" --include="*.cs" .

# Find native library loading
grep -r "wkhtmltopdf\|libwkhtmltox" --include="*.cs" --include="*.csproj" .

# Find GlobalSettings/ObjectSettings usage
grep -r "GlobalSettings\|ObjectSettings\|MarginSettings" --include="*.cs" .
# Find DinkToPdf namespace usage
grep -r "using DinkToPdf\|using Haukcode" --include="*.cs" .

# Find converter usage
grep -r "SynchronizedConverter\|BasicConverter\|HtmlToPdfDocument" --include="*.cs" .

# Find native library loading
grep -r "wkhtmltopdf\|libwkhtmltox" --include="*.cs" --include="*.csproj" .

# Find GlobalSettings/ObjectSettings usage
grep -r "GlobalSettings\|ObjectSettings\|MarginSettings" --include="*.cs" .
SHELL

記錄目前的全局設定物件設定設定。 找出任何可以移除的本機庫載入程式碼。

程式碼更新任務

1.移除 DinkToPdf NuGet 套件 2.安裝 IronPdf NuGet 套件 3.更新命名空間匯入,從 DinkToPdfIronPdf 4.將同步轉換器改為 ChromePdfRenderer 5.將<編碼>HtmlToPdfDocument</編碼模式轉換為直接方法呼叫 6.將全局設定轉換為 RenderingOptions 7.將物件設定轉換為 RenderingOptions 8.更新占位符語法 ([page]{page},[toPage]{total-pages}) 9.在啟動時增加 IronPdf 授權初始化功能

基礎結構清理任務

1.刪除原生二進位檔 (libwkhtmltox.*) 2.移除原生程式庫載入程式碼 3.如果存在,移除 CustomAssemblyLoadContext 4.更新依賴注入 (不再需要單件) 5.移除原生二進位檔的平台偵測程式碼

後遷移測試

轉移後,驗證這些方面:

  • 測試 HTML 至 PDF 的轉換
  • 測試 URL 至 PDF 的轉換
  • 確認頁面設定(大小、方向、邊界)
  • 使用占位符驗證頁首和頁尾
  • 使用實際的 HTML 範本進行測試
  • 負載下的效能測試

遷移到IronPDF的主要優點。

從 Haukcode.DinkToPdf 轉移到IronPDF提供了幾個關鍵優勢:

安全性:消除 CVE-2022-35583 (SSRF) 和其他永遠不會修補的 wkhtmltopdf 漏洞。

現代化的渲染引擎:使用積極更新的 Chromium,而非 2015 年廢棄的 Qt WebKit。完整的 HTML5、CSS3 與 JavaScript 支援。

No Native Binaries:自成一格的函式庫,無須管理特定平台的 DLL。 簡化跨 Windows、Linux 和 macOS 的部署。

線程安全:無單機需求--可在任何模式中自由使用<代碼>ChromePdfRenderer</代碼包括按要求實體化。

更簡單的 API:直接方法呼叫(RenderHtmlAsPdf()RenderUrlAsPdf())取代複雜的文件物件建構。

主動開發:隨著 .NET 10 和 C# 14 的採用增加至 2026 年,IronPDF 的定期更新可確保與目前和未來的 .NET 版本相容。

結論

Haukcode.DinkToPdf 作為 DinkToPdf 專案的延續,維持 .NET Core 對於基於 wkhtmltopdf 的 PDF 產生的相容性。 然而,底層的 wkhtmltopdf 二進位檔已於 2023 年歸檔,導致 CVE-2022-35583 等關鍵安全漏洞永遠無法修補。 每天都有應用程式繼續使用 Haukcode.DinkToPdf,基礎架構仍然面臨 SSRF 攻擊的風險。

IronPDF 提供了一個現代化、安全的替代方案,其 Chromium 演算引擎可處理當代的網頁標準。 遷移路徑很簡單:移除 DinkToPdf 套件和原生二進位檔,以直接渲染方法取代文件建構,並更新佔位符語法。

立即使用 免費試用 IronPDF 開始您的遷移,並消除基於 wkhtmltopdf 解決方案的固有安全漏洞。

如需全面的實施指導,請探索 IronPDF 文件教學

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。