如何用 C# 從 TuesPechkin 轉移到 IronPDF
TuesPechkin 是 wkhtmltopdf 函式庫的線程安全封裝程式,多年來一直協助 .NET 開發人員將 HTML 轉換為 PDF。 然而,wkhtmltopdf 的底層技術最後一次更新是在 2015 年,並於 2022 年 12 月正式廢棄。這造成了重要的安全性、穩定性和渲染限制,開發團隊再也不能忽視。
本指南提供了從星期二到IronPDF的完整轉換路徑,並提供分步說明、程式碼比較以及實用範例,可供評估此轉換的 .NET 專業開發人員使用。
為何立即從星期二遷移?
對於具有安全意識的開發團隊而言,從星期二轉移的決定不再是可有可無的。 底層的 wkhtmltopdf 函式庫存在永遠無法修復的嚴重未修補漏洞。
關鍵安全漏洞:CVE-2022-35583
| 屬性 | 價值 |
|---|---|
| CVE ID | CVE-2022-35583 |
| 嚴重性 | CRITICAL (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" />
這可讓攻擊者存取 AWS/Azure/GCP 元資料端點、竊取內部 API 資料、埠掃描內部網路,以及外洩敏感組態。
技術危機
TuesPechkin 包裝了 wkhtmltopdf,它使用 Qt WebKit 4.8 - 古老的 Chrome 前世紀技術。 這意味著
- 不支援 Flexbox
- 不支援 CSS 網格
- 破碎的 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
IronPDFvs TuesPechkin:功能比較
了解架構上的差異有助於技術決策者評估遷移投資:
| 特點 | 星期二 | IronPDF |
|---|---|---|
| 執照 | 免費 (MIT 授權) | 商業的 |
| 線程安全 | 需要手動管理 | 本地支援 |
| 貨幣 | 功能有限,可能會在負載下當機 | 穩健、可處理高並發性 |
| 開發 | 未激活,最近更新日期為 2015 年 | 積極、持續的改進 |
| 易用性 | 複雜的設定 | 使用指南方便使用者 |
| 說明文件 | 基本的 | 包含大量範例 |
| 安全性 | ❌ 關鍵 CVE | ✅ 無已知漏洞 |
| HTML至PDF | ⚠️ 過時的 WebKit | ✅ 現代 Chromium |
| CSS3。 | ❌ 部分 | ✅ 已支援 |
| Flexbox/網格 | ❌ 不支援 | ✅ 已支援 |
| JavaScript。 | ⚠️ 不可靠 | ✅ 完全 ES6+ |
| PDF 操作 | ❌ 不可用 | ✅ 全文 |
| 數位簽名 | ❌ 不可用 | ✅ 全文 |
| PDF/A合規性 | ❌ 不可用 | ✅ 全文 |
| 表格填寫 | ❌ 不可用 | ✅ 全文 |
| 水印。 | ❌ 不可用 | ✅ 全文 |
| 合併/分割 | ❌ 不可用 | ✅ 全文 |
快速入門:從IronPDF遷移到 I TuesPechkin。
只要完成這些基本步驟,就可以立即開始遷移。
步驟 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
安裝 IronPDF:
# Install IronPDF
dotnet add package IronPdf
# Install IronPDF
dotnet add package IronPdf
步驟 2:移除原生二進位檔案
從您的專案中刪除這些檔案和資料夾:
wkhtmltox.dllwkhtmltopdf.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;
' Before (TuesPechkin)
Imports TuesPechkin
Imports TuesPechkin.Wkhtmltox.Win64
' After (IronPDF)
Imports IronPdf
步驟 4:初始化授權
在應用程式啟動時加入授權初始化:
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
程式碼遷移範例
將 HTML 轉換為 PDF
最常見的使用案例展示了這些 .NET PDF 函式庫的複雜性差異。
TuesPechkin 方法:
// 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);
}
}
Imports TuesPechkin
Imports System.IO
Class Program
Shared Sub Main()
Dim converter = New StandardConverter(
New RemotingToolset(Of PdfToolset)(
New Win64EmbeddedDeployment(
New TempFolderDeployment())))
Dim html As String = "<html><body><h1>Hello World</h1></body></html>"
Dim pdfBytes As Byte() = converter.Convert(New HtmlToPdfDocument With {
.Objects = {New ObjectSettings With {.HtmlText = html}}
})
File.WriteAllBytes("output.pdf", pdfBytes)
End Sub
End Class
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");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim html As String = "<html><body><h1>Hello World</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
End Sub
End Class
TuesPechkin 版本需要建立一個具有複雜初始化鏈的 StandardConverter:RemotingToolset、Win64EmbeddedDeployment 和 TempFolderDeployment。 您也必須手動將位元組寫入檔案。
IronPDF 完全消除了這一儀式。 建立 ChromePdfRenderer,渲染 HTML,並儲存。 程式碼是自我說明的,不需要瞭解部署工具集或特定平台的二進位管理。
如需進階的 HTML 至IronPDF情境,請參閱 HTML 至 PDF 轉換指南。
將 URL 轉換為 PDF
URL 到 PDF 的轉換也顯示出類似的複雜性差異。
TuesPechkin 方法:
// 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);
}
}
Imports TuesPechkin
Imports System.IO
Class Program
Shared Sub Main()
Dim converter = New StandardConverter(
New RemotingToolset(Of PdfToolset)(
New Win64EmbeddedDeployment(
New TempFolderDeployment())))
Dim pdfBytes As Byte() = converter.Convert(New HtmlToPdfDocument With {
.Objects = {
New ObjectSettings With {
.PageUrl = "https://www.example.com"
}
}
})
File.WriteAllBytes("webpage.pdf", pdfBytes)
End Sub
End Class
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");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End Class
TuesPechkin 使用 ObjectSettings.PageUrl 嵌套在 HtmlToPdfDocument 中。IronPDF提供了一個專門的 RenderUrlAsPdf 方法,可以清楚地表達意圖。
探索URL至PDF文件的認證和自訂標頭選項。
自訂渲染設定
頁面方向、紙張大小和頁邊需要不同的配置方法。
TuesPechkin 方法:
// 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 = {
Orientation = 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 = {
Orientation = 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);
}
}
Imports TuesPechkin
Imports System.IO
Module Program
Sub Main()
Dim converter = New StandardConverter(
New RemotingToolset(Of PdfToolset)(
New Win64EmbeddedDeployment(
New TempFolderDeployment())))
Dim html As String = "<html><body><h1>Custom PDF</h1></body></html>"
Dim document = New HtmlToPdfDocument With {
.GlobalSettings = New GlobalSettings With {
.Orientation = GlobalSettings.PdfOrientation.Landscape,
.PaperSize = GlobalSettings.PdfPaperSize.A4,
.Margins = New MarginSettings With {.Unit = Unit.Millimeters, .Top = 10, .Bottom = 10}
},
.Objects = {
New ObjectSettings With {.HtmlText = html}
}
}
Dim pdfBytes As Byte() = converter.Convert(document)
File.WriteAllBytes("custom.pdf", pdfBytes)
End Sub
End Module
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");
}
}
Imports IronPdf
Imports IronPdf.Engines.Chrome
Imports System
Module Program
Sub Main()
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 10
renderer.RenderingOptions.MarginBottom = 10
Dim html As String = "<html><body><h1>Custom PDF</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("custom.pdf")
End Sub
End Module
TuesPechkin 將設定分為 GlobalSettings(文件範圍選項)和 ObjectSettings(內容)。IronPDF將所有內容整合到 RenderingOptions 中,並使用清晰、易於發現的屬性名稱。
星期二API 到IronPDF的映射參考。
此對應可透過顯示直接的 API 對應關係來加速遷移:
| 星期二 | IronPDF |
|---|---|
StandardConverter |
ChromePdfRenderer |
ThreadSafeConverter |
ChromePdfRenderer |
HtmlToPdfDocument |
方法參數 |
GlobalSettings |
RenderingOptions |
ObjectSettings.HtmlText |
RenderHtmlAsPdf(html) |
ObjectSettings.PageUrl |
RenderUrlAsPdf(url) |
GlobalSettings.PaperSize |
RenderingOptions.PaperSize |
GlobalSettings.Orientation |
RenderingOptions.PaperOrientation |
MarginSettings |
MarginTop,MarginBottom,等等。 |
[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!
' Before (TuesPechkin)
Dim converter = New StandardConverter(
New RemotingToolset(Of PdfToolset)(
New Win64EmbeddedDeployment(
New TempFolderDeployment())))
' After (IronPDF)
Dim renderer = New ChromePdfRenderer()
' That's it!
問題 2:線程安全崩潰
問題:星期二的 ThreadSafeConverter 在高負載下仍然崩潰,並出現 AccessViolationException。
解決方案:IronPDF具有原生線程安全功能 - 無需特殊設定:
//IronPDFis inherently thread-safe
var renderer = new ChromePdfRenderer();
// Use from any thread without crashes
//IronPDFis inherently thread-safe
var renderer = new ChromePdfRenderer();
// Use from any thread without crashes
'IronPDF is inherently thread-safe
Dim renderer As New ChromePdfRenderer()
' Use from any thread without crashes
問題 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}"
問題 4:CSS 佈局破損
問題:因為 wkhtmltopdf 使用 Qt WebKit 4.8,所以 Flexbox 和 Grid 佈局在星期二中無法運作。
解決方案:使用適當的現代 CSS 與 IronPDF:
// 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!
' Remove table-based workarounds, use modern CSS
Dim html As String = "
<div style='display: flex; justify-content: space-between;'>
<div>Left</div>
<div>Right</div>
</div>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
' Works correctly with Chromium!
第 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
星期二移轉清單
遷移前的任務
審核您的程式碼庫,找出所有星期二的用法:
grep -r "using TuesPechkin" --include="*.cs" .
grep -r "ThreadSafeConverter\|RemotingToolset" --include="*.cs" .
grep -r "using TuesPechkin" --include="*.cs" .
grep -r "ThreadSafeConverter\|RemotingToolset" --include="*.cs" .
記錄目前 GlobalSettings 配置(紙張尺寸、方向、邊距)。 文件 ObjectSettings 配置(HTML 內容、URL)。 確定轉換的 header/footer 實作。 找出所有 wkhtmltopdf 二進位檔以便移除。
程式碼更新任務
1.移除星期二NuGet 套件 2.移除原生 wkhtmltopdf 二進位檔 3.安裝IronPDFNuGet 套件
- 使用語句從
TuesPechkin更新至IronPdf5.在啟動時加入授權金鑰初始化 - 將轉換器替換為
ChromePdfRenderer - 將
GlobalSettings轉換為RenderingOptions - 將
ObjectSettings轉換為方法參數 9.更新頁邊配置至個別屬性 - 將頁首/頁尾語法更新為基於 HTML 的
HtmlHeaderFooter - 修正頁佔位符語法(
[page]→{page}) 12.移除所有部署/工具集程式碼
後遷移測試
轉移後,驗證這些方面:
- 執行所有單元測試
- 測試線程安全情境 (IronPDF 可處理多執行緒而不會當機)
- 比較 PDF 輸出品質 (Chromium 的渲染更精確)
- 驗證 CSS 呈現 (Flexbox 和 Grid 現在可以運作)
- 測試 JavaScript 執行 (現在支援 ES6+)
- 測試頁首/頁尾的呈現
- 效能測試批次作業
- 安全掃描以確認沒有 wkhtmltopdf 的二進位檔存在
遷移到IronPDF的主要優點。
從星期二轉移到IronPDF提供了幾個關鍵優勢:
安全性:CVE-2022-35583和其他 wkhtmltopdf 漏洞已消除。IronPDF的 Chromium 引擎會定期接受安全更新。
原生執行緒安全性:不再需要複雜的設定。 不再出現 AccessViolationException 在負載下崩潰的情況。IronPDF自動處理並發。
現代渲染引擎:完全支援 CSS3、Flexbox、Grid 和 ES6+ JavaScript。 您的 PDF 將完全呈現在現代瀏覽器中的內容。
簡化部署:無需管理特定於平台的二進位檔案。 沒有 RemotingToolset、Win64EmbeddedDeployment 或 TempFolderDeployment 儀式。 只需安裝 NuGet 套件即可。
積極開發:隨著 .NET 10 和 C# 14 的普及,IronPDF 將持續更新,確保與目前和未來的 .NET 版本相容。
擴充功能:星期二僅將 HTML 轉換為 PDF。IronPDF增加了 PDF 操作、數位簽署、PDF/A 合規性、表格填寫、水印以及合併/分割操作。

