跳過到頁腳內容
MIGRATION GUIDES

How to Migrate from TuesPechkin to IronPDF in C#

多年來,TuesPechkin 一直作為 wkhtmltopdf 庫的線程安全包裝器,幫助 .NET 開發人員將 HTML 轉換為 PDF。 然而,底層 wkhtmltopdf 技術最後一次更新是在 2015 年,並於 2022 年 12 月正式停止使用。這造成了嚴重的安全性、穩定性和渲染方面的限制,開發團隊再也不能忽視這些限制了。

本指南提供了從 週二佩奇金 到 IronPDF 的完整遷移路徑,包括逐步說明、程式碼比較和實用範例,供正在評估此過渡的專業 .NET 開發人員參考。

為什麼現在要從TuesPechkin遷移?

對於注重安全性的開發團隊來說,從 週二佩奇金 遷移已經不再是可選項。 底層 wkhtmltopdf 庫存在尚未修補的嚴重漏洞,這些漏洞永遠不會被修復。

嚴重安全漏洞:CVE-2022-35583

屬性 價值
CVE ID CVE-2022-35583
嚴重程度 評分:9.8/10
攻擊向量 網路
地位 永遠不會修復
做作的 所有 週二佩奇金 版本

wkhtmltopdf 的維護者明確表示他們不會修復安全漏洞。 使用 週二佩奇金 的每個應用程式都永久暴露於伺服器端請求偽造 (SSRF) 攻擊之下。

攻擊原理

在處理使用者提供的 HTML 時,攻擊者可以注入惡意內容:


<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-admin-panel:8080/api/users?export=all" />

<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-admin-panel:8080/api/users?export=all" />
HTML

這使得攻擊者能夠存取 AWS/Azure/GCP 元資料端點,竊取內部 API 數據,掃描內部網路端口,並竊取敏感配置。

技術危機

TuesPechkin 封裝了 wkhtmltopdf,而 wkhtmltopdf 使用的是 Qt WebKit 4.8——一種古老的、Chrome 時代之前的技術。 這意味著:

  • 不支援 Flexbox
  • 不支援 CSS Grid
  • JavaScript 執行失敗 不支援 ES6+

穩定危機

即使使用了宣傳的ThreadSafeConverter ,TuesPechkin 在高負載下仍然會崩潰:

// ❌ 週二佩奇金 - "ThreadSafeConverter" still crashes
var converter = new TuesPechkin.ThreadSafeConverter(
    new TuesPechkin.RemotingToolset<PechkinBindings>());

// Under high load, you'll see:
// System.AccessViolationException: Attempted to read or write protected memory
// Process terminated unexpectedly
// Converter hangs indefinitely
// ❌ 週二佩奇金 - "ThreadSafeConverter" still crashes
var converter = new TuesPechkin.ThreadSafeConverter(
    new TuesPechkin.RemotingToolset<PechkinBindings>());

// Under high load, you'll see:
// System.AccessViolationException: Attempted to read or write protected memory
// Process terminated unexpectedly
// Converter hangs indefinitely
$vbLabelText   $csharpLabel

IronPDF 與 TuesPechkin:功能對比

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

特徵 週二佩奇金 IronPDF
執照 免費(MIT許可證) 商業的
螺紋安全 需要人工管理 原生支援
並發性 功能有限,負載過高時可能會崩潰 健壯,可處理高並發
發展 已失效,上次更新時間為 2015 年 積極、持續的改進
易用性 複雜的設定 使用者友好,附帶指南
文件 基本的 包含大量範例
安全 ❌ 嚴重漏洞 ✅ 無已知漏洞
HTML 轉 PDF ⚠️ 過時的 WebKit ✅ 現代鉻
CSS3 ❌ 部分 ✅ 全力支持
Flexbox/Grid ❌ 不支持 ✅ 全力支持
JavaScript ⚠️ 不可靠 ✅ 完全 ES6+
PDF 處理 ❌ 暫無供應 ✅ 已完成
數位簽名 ❌ 暫無供應 ✅ 已完成
PDF/A 合規性 ❌ 暫無供應 ✅ 已完成
表格填寫 ❌ 暫無供應 ✅ 已完成
水印 ❌ 暫無供應 ✅ 已完成
合併/拆分 ❌ 暫無供應 ✅ 已完成

快速入門:TuesPechkin 到 IronPDF 的遷移

透過這些基礎步驟,遷移工作可以立即開始。

步驟 1:替換 NuGet 套件

刪除所有 週二佩奇金 套件:

# Remove 週二佩奇金 and all related packages
dotnet remove package TuesPechkin
dotnet remove package TuesPechkin.Wkhtmltox.Win64
dotnet remove package TuesPechkin.Wkhtmltox.Win32
# Remove 週二佩奇金 and all related packages
dotnet remove package TuesPechkin
dotnet remove package TuesPechkin.Wkhtmltox.Win64
dotnet remove package TuesPechkin.Wkhtmltox.Win32
SHELL

安裝 IronPDF:

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

步驟 2:刪除本地二進位文件

從項目中刪除以下文件和資料夾:

  • wkhtmltox.dll
  • wkhtmltopdf.exe
  • 任何wkhtmlto*文件
  • TuesPechkin.Wkhtmltox資料夾

步驟 3:更新命名空間

將 週二佩奇金 命名空間替換為 IronPdf 命名空間:

// Before (TuesPechkin)
using TuesPechkin;
using TuesPechkin.Wkhtmltox.Win64;

// After (IronPDF)
using IronPdf;
// Before (TuesPechkin)
using TuesPechkin;
using TuesPechkin.Wkhtmltox.Win64;

// After (IronPDF)
using IronPdf;
$vbLabelText   $csharpLabel

步驟 4:初始化許可證

在應用程式啟動時新增許可證初始化:

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

程式碼遷移範例

將 HTML 轉換為 PDF

最常見的用例反映了這些 .NET PDF 程式庫之間的複雜性差異。

週二佩奇金方法:

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

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        string html = "<html><body><h1>Hello World</h1></body></html>";
        byte[] pdfBytes = converter.Convert(new HtmlToPdfDocument
        {
            Objects = { new ObjectSettings { HtmlText = html } }
        });

        File.WriteAllBytes("output.pdf", pdfBytes);
    }
}
// NuGet: Install-Package TuesPechkin
using TuesPechkin;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        string html = "<html><body><h1>Hello World</h1></body></html>";
        byte[] pdfBytes = converter.Convert(new HtmlToPdfDocument
        {
            Objects = { new ObjectSettings { HtmlText = html } }
        });

        File.WriteAllBytes("output.pdf", pdfBytes);
    }
}
$vbLabelText   $csharpLabel

IronPDF 方法:

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

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

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

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

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

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

        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

TuesPechkin 版本需要建立一個具有複雜初始化鏈的StandardConverterRemotingToolsetWin64EmbeddedDeploymentTempFolderDeployment 。 您還必須手動將位元組寫入文件。

IronPDF 完全省略了這個步驟。 建立一個ChromePdfRenderer ,渲染 HTML,然後儲存。 程式碼具有自我文檔性,無需了解部署工具集或特定於平台的二進位檔案管理。

如需更進階的 HTML 轉 PDF 場景,請參閱HTML 轉 PDF 轉換指南

將 URL 轉換為 PDF

URL 轉 PDF 轉換也存在類似的複雜性差異。

週二佩奇金方法:

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

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        byte[] pdfBytes = converter.Convert(new HtmlToPdfDocument
        {
            Objects = {
                new ObjectSettings {
                    PageUrl = "https://www.example.com"
                }
            }
        });

        File.WriteAllBytes("webpage.pdf", pdfBytes);
    }
}
// NuGet: Install-Package TuesPechkin
using TuesPechkin;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        byte[] pdfBytes = converter.Convert(new HtmlToPdfDocument
        {
            Objects = {
                new ObjectSettings {
                    PageUrl = "https://www.example.com"
                }
            }
        });

        File.WriteAllBytes("webpage.pdf", pdfBytes);
    }
}
$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");
    }
}
$vbLabelText   $csharpLabel

TuesPechkin 使用嵌套在HtmlToPdfDocument中的ObjectSettings.PageUrl 。 IronPDF 提供了一個專門的RenderUrlAsPdf方法,可以清楚地表達意圖。

查看指向 PDF 文件的 URL ,以了解身份驗證和自訂標頭選項。

自訂渲染設定

頁面方向、紙張尺寸和頁邊距需要不同的配置方法。

週二佩奇金方法:

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

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        string html = "<html><body><h1>Custom PDF</h1></body></html>";

        var document = new HtmlToPdfDocument
        {
            GlobalSettings = {
                方向 = GlobalSettings.PdfOrientation.Landscape,
                PaperSize = GlobalSettings.PdfPaperSize.A4,
                Margins = new MarginSettings { Unit = Unit.Millimeters, Top = 10, Bottom = 10 }
            },
            Objects = {
                new ObjectSettings { HtmlText = html }
            }
        };

        byte[] pdfBytes = converter.Convert(document);
        File.WriteAllBytes("custom.pdf", pdfBytes);
    }
}
// NuGet: Install-Package TuesPechkin
using TuesPechkin;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        string html = "<html><body><h1>Custom PDF</h1></body></html>";

        var document = new HtmlToPdfDocument
        {
            GlobalSettings = {
                方向 = GlobalSettings.PdfOrientation.Landscape,
                PaperSize = GlobalSettings.PdfPaperSize.A4,
                Margins = new MarginSettings { Unit = Unit.Millimeters, Top = 10, Bottom = 10 }
            },
            Objects = {
                new ObjectSettings { HtmlText = html }
            }
        };

        byte[] pdfBytes = converter.Convert(document);
        File.WriteAllBytes("custom.pdf", pdfBytes);
    }
}
$vbLabelText   $csharpLabel

IronPDF 方法:

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
using System;

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

        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;

        string html = "<html><body><h1>Custom PDF</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

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

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

        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;

        string html = "<html><body><h1>Custom PDF</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("custom.pdf");
    }
}
$vbLabelText   $csharpLabel

TuesPechkin 將設定分為GlobalSettings (用於文件範圍的選項)和ObjectSettings用於內容)。 IronPDF 將所有內容整合到RenderingOptions中,並使用清晰易懂的屬性名稱。

週二佩奇金 API 到 IronPDF 映射參考

此映射透過顯示直接的 API 等效項來加速遷移:

週二佩奇金 IronPDF 筆記
StandardConverter ChromePdfRenderer 無需複雜的初始化
ThreadSafeConverter ChromePdfRenderer 原生螺紋安全
HtmlToPdfDocument 方法參數 無需文檔對象
GlobalSettings RenderingOptions 配置選項
ObjectSettings.HtmlText RenderHtmlAsPdf(html) 直接渲染
ObjectSettings.PageUrl RenderUrlAsPdf(url) URL渲染
GlobalSettings.PaperSize RenderingOptions.PaperSize 紙張尺寸
GlobalSettings.Orientation RenderingOptions.PaperOrientation 方向
MarginSettings MarginTopMarginBottom等。 個體邊際屬性
[page]佔位符 {page}佔位符 頁碼文法
[toPage]佔位符 {total-pages}佔位符 總頁語法
RemotingToolset 不需要 無部署管理
Win64EmbeddedDeployment 不需要 無平台二進位文件
TempFolderDeployment 不需要 不進行臨時資料夾管理

常見遷移問題及解決方案

問題 1:複雜的初始化程式碼

問題: 週二佩奇金 需要複雜的轉換器設定和部署工具集。

解決方案: IronPDF 很簡單:

// Before (TuesPechkin)
var converter = new StandardConverter(
    new RemotingToolset<PdfToolset>(
        new Win64EmbeddedDeployment(
            new TempFolderDeployment())));

// After (IronPDF)
var renderer = new ChromePdfRenderer();
// That's it!
// Before (TuesPechkin)
var converter = new StandardConverter(
    new RemotingToolset<PdfToolset>(
        new Win64EmbeddedDeployment(
            new TempFolderDeployment())));

// After (IronPDF)
var renderer = new ChromePdfRenderer();
// That's it!
$vbLabelText   $csharpLabel

問題二:線程安全崩潰

問題: 週二佩奇金 的ThreadSafeConverter在高負載下仍然崩潰,並出現AccessViolationException

解決方案: IronPDF 本身就具有執行緒安全性,無需特殊配置:

// IronPDF is inherently thread-safe
var renderer = new ChromePdfRenderer();
// Use from any thread without crashes
// IronPDF is inherently thread-safe
var renderer = new ChromePdfRenderer();
// Use from any thread without crashes
$vbLabelText   $csharpLabel

問題 3:頁碼佔位符語法

問題: 週二佩奇金 使用[page][toPage]佔位符。

解決方案:更新 IronPDF 的佔位符語法:

// Before (TuesPechkin)
"Page [page] of [toPage]"

// After (IronPDF)
"Page {page} of {total-pages}"
// Before (TuesPechkin)
"Page [page] of [toPage]"

// After (IronPDF)
"Page {page} of {total-pages}"
$vbLabelText   $csharpLabel

問題 4:CSS 佈局錯誤

問題:由於 wkhtmltopdf 使用了 Qt WebKit 4.8,因此 週二佩奇金 中 Flexbox 和 Grid 佈局不起作用。

解決方案:在 IronPDF 中使用正確的現代 CSS:

// Remove table-based workarounds, use modern CSS
var html = @"
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>";

var pdf = renderer.RenderHtmlAsPdf(html);
// Works correctly with Chromium!
// Remove table-based workarounds, use modern CSS
var html = @"
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>";

var pdf = renderer.RenderHtmlAsPdf(html);
// Works correctly with Chromium!
$vbLabelText   $csharpLabel

問題 5:原生二進位管理

問題: 週二佩奇金 需要平台特定的 wkhtmltopdf 二進位和路徑配置。

解決方案: IronPDF 透過 NuGet 處理所有依賴項-無需管理任何原生二進位檔案:

# Just install the package
dotnet add package IronPdf
# No wkhtmltopdf binaries needed
# Just install the package
dotnet add package IronPdf
# No wkhtmltopdf binaries needed
SHELL

週二佩奇金遷移清單

遷移前任務

審核您的程式碼庫,找出所有 週二佩奇金 的使用情況:

grep -r "using TuesPechkin" --include="*.cs" .
grep -r "ThreadSafeConverter\|RemotingToolset" --include="*.cs" .
grep -r "using TuesPechkin" --include="*.cs" .
grep -r "ThreadSafeConverter\|RemotingToolset" --include="*.cs" .
SHELL

記錄目前GlobalSettings配置(紙張尺寸、方向、邊距)。 文檔ObjectSettings配置(HTML 內容、URL)。 確定用於轉換的頁首/頁尾實作方式。 找到所有 wkhtmltopdf 二進位檔案並將其刪除。

程式碼更新任務

  1. 刪除 週二佩奇金 NuGet 套件
  2. 刪除原生 wkhtmltopdf 二進位文件
  3. 安裝 IronPdf NuGet 套件
  4. 使用從TuesPechkinIronPdf語句進行更新
  5. 新增啟動時許可證金鑰初始化功能
  6. 將轉換器替換為ChromePdfRenderer
  7. GlobalSettings轉換為RenderingOptions
  8. ObjectSettings轉換為方法參數
  9. 將邊距配置更新為各個屬性
  10. 將頁首/頁尾語法更新為基於 HTML 的HtmlHeaderFooter
  11. 修正頁面佔位符語法( [page]{page}
  12. 刪除所有部署/工具集程式碼

遷移後測試

遷移完成後,請確認以下幾個面向:

  • 執行所有單元測試
  • 測試線程安全場景(IronPDF 可以處理多線程而不會崩潰)
  • 對比PDF輸出品質(Chromium渲染更精準)
  • 驗證 CSS 渲染效果(Flexbox 和 Grid 現在都能正常運作)
  • 測試 JavaScript 執行(現已支援 ES6+)
  • 測試頁首/頁尾渲染
  • 效能測試批次操作
  • 安全性掃描以確認沒有殘留的 wkhtmltopdf 二進位。

遷移到 IronPDF 的主要優勢

從 週二佩奇金 遷移到 IronPDF 可以帶來幾個關鍵優勢:

安全性: CVE-2022-35583 和其他 wkhtmltopdf 漏洞已消除。 IronPDF 的 Chromium 引擎會定期收到安全更新。

原生執行緒安全性:無需再進行複雜的ThreadSafeConverter設定。 在高負載下不再出現AccessViolationException崩潰。 IronPDF 可以自動處理並發問題。

現代渲染引擎:完全支援 CSS3、Flexbox、Grid 和 ES6+ JavaScript。 您的 PDF 檔案在現代瀏覽器中的顯示效果與內容呈現效果完全一致。

簡化部署:無需管理特定於平台的二進位檔案。 無需RemotingToolsetWin64EmbeddedDeploymentTempFolderDeployment儀式。 只需安裝 NuGet 套件即可。

積極開發:隨著 .NET 10 和 C# 14 的普及,IronPDF 將持續更新,確保與目前和未來的 .NET 版本相容。

擴充功能: 週二佩奇金 僅將 HTML 轉換為 PDF。 IronPDF 增加了 PDF 操作、數位簽名、PDF/A 合規性、表單填寫、浮水印以及合併/分割操作。

Curtis Chau
技術撰稿人

Curtis Chau 擁有電腦科學學士學位(卡爾頓大學),專長於前端開發,精通 Node.js、TypeScript、JavaScript 和 React。Curtis 對製作直覺且美觀的使用者介面充滿熱情,他喜歡使用現代化的架構,並製作結構良好且視覺上吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 也有濃厚的興趣,他喜歡探索整合硬體與軟體的創新方式。在空閒時間,他喜歡玩遊戲和建立 Discord bots,將他對技術的熱愛與創意結合。