如何用 C# 從 Ghostscript GPL 轉換到 IronPDF
從Ghostscript GPL轉換到IronPDF可將您的 .NET PDF 工作流程從命令列處理及基於字串的切換操作轉換為類型安全、支援 IntelliSense 的本機 .NET API。 本指南提供了一個全面、循序漸進的遷移路徑,可消除 Professional .NET 開發人員對 AGPL許可證的疑慮和外部二進位依賴。
為什麼要從Ghostscript GPL轉移到 IronPDF?
Ghostscript GPL的挑戰
Ghostscript GPL 是一款歷史悠久的 PostScript/PDF 解譯器,已有數十年的歷史,但在現代 .NET 應用程式中使用它卻面臨重大的挑戰:
- AGPL 授權限制:Ghostscript GPL的 AGPL 授權要求,如果您散佈使用該授權的軟體,則必須發佈您的原始程式碼——除非您從 Artifex 購買昂貴的商業授權。 這種"病毒式"的授權模式會為專屬應用程式帶來重大的法律風險。
2.命令列介面:Ghostscript GPL本質上就是一個命令列工具。 從 C# 使用它需要產生進程、傳遞字串參數和解析輸出,這是一種脆弱且容易出錯的方法。
3.外部二進位依賴項:您必須單獨安裝 Ghostscript GPL,管理 PATH 變量,並確保跨部署環境的版本相容性。 32 位元系統和 64 位元系統需要不同的 DLL 檔案(gsdll32.dll vs gsdll64.dll)。
4.不支援原生 HTML 轉 PDF:Ghostscript GPL無法直接將 HTML 轉換為 PDF。 您需要先使用其他工具將 HTML 轉換為 PostScript,然後再使用Ghostscript GPL將 PostScript 轉換為 PDF - 這是一個具有外部依賴性的多步驟管道。
5.複雜的 Switch 語法:操作透過晦澀的命令列開關進行控制,例如 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=...。 沒有 IntelliSense、沒有類型安全,而且容易打錯字。
6.錯誤處理:錯誤以文字字串的形式透過 stderr 輸出,需要進行解析而不是結構化的異常處理。
7.進程管理開銷:每個操作都會產生一個單獨的進程,這增加了錯誤處理、逾時和資源清理的開銷和複雜性。
Ghostscript GPL與IronPDF的比較
| 範疇 | Ghostscript GPL | IronPDF |
|---|---|---|
| 許可證 | AGPL(病毒式)或昂貴的商業 | 商業用語清晰 |
| 整合 | 命令列程序產生 | 原生 .NET 函式庫 |
| API 設計 | 基於字串的切換 | 類型化、支援 IntelliSense 的 API |
| 錯誤處理 | 解析 stderr 文字 | .NET 例外 |
| HTML 至 PDF | 不支援(需要外部工具) | 內建 Chromium 引擎 |
| 依賴 | 外部二進制安裝 | 自包含的 NuGet 套件 |
| 部署 | 設定 PATH、複製 DLL | 只需加入 NuGet 參考資料 |
| 線程安全 | 僅限於流程隔離 | 線程安全的設計 |
| 現代 .NET | 有限支援 | 完全支援 .NET 6/7/8/9/10 |
| 同步支援 | 以流程為基礎 | 原生 async/await |
對於計劃在 2025 年和 2026 年之前採用 .NET 10 和 C# 14 的團隊而言,IronPDF 提供了一個面向未來的基礎,可與現代 .NET 模式原生整合。
遷移複雜性評估
按功能估計的工作量
| 特點 | 遷移複雜性 |
|---|---|
| PDF 至圖片 | 低 |
| 合併 PDF | 低 |
| 壓縮 PDF | 低 |
| PDF 最佳化 | 低 |
| 加密 | 語言 |
| 頁面抽取 | 低 |
| PostScript 至 PDF | 中高級 |
| 自訂開關 | 中高級 |
範式轉移
Ghostscript GPL 遷移的根本轉變在於從命令列程序執行轉變為類型化的 .NET API 呼叫:
Ghostscript GPL: "將這些字串開關傳給外部程序
IronPDF: "在 .NET 物件上呼叫這些方法
開始之前
先決條件
- .NET 版本:IronPDF支援 .NET Framework 4.6.2+ 和 .NET Core 2.0+ / .NET 5/6/7/8/9+ 2.許可證密鑰:請從ironpdf.com取得您的IronPDF許可證密鑰。 3.備份:建立一個用於遷移工作的分支
確認所有Ghostscript GPL使用情況
# Find all Ghostscript.NET references
grep -r "Ghostscript\.NET\|GhostscriptProcessor\|GhostscriptRasterizer\|gsdll" --include="*.cs" .
# Find direct process calls to Ghostscript
grep -r "gswin64c\|gswin32c\|gs\|ProcessStartInfo.*ghost" --include="*.cs" .
# Find package references
grep -r "Ghostscript" --include="*.csproj" .
# Find all Ghostscript.NET references
grep -r "Ghostscript\.NET\|GhostscriptProcessor\|GhostscriptRasterizer\|gsdll" --include="*.cs" .
# Find direct process calls to Ghostscript
grep -r "gswin64c\|gswin32c\|gs\|ProcessStartInfo.*ghost" --include="*.cs" .
# Find package references
grep -r "Ghostscript" --include="*.csproj" .
NuGet 套件變更
# Remove Ghostscript.NET
dotnet remove package Ghostscript.NET
# Install IronPDF
dotnet add package IronPdf
# Remove Ghostscript.NET
dotnet remove package Ghostscript.NET
# Install IronPDF
dotnet add package IronPdf
移除Ghostscript GPL相依性
遷移後:
- 從伺服器解除安裝 Ghostscript GPL
- 從部署移除
gsdll32.dll/gsdll64.dll - 移除Ghostscript GPL的 PATH 設定
- 刪除所有
GhostscriptVersionInfo引用
快速啟動遷移
步驟 1:更新授權組態
之前 (Ghostscript GPL):
AGPL 下的Ghostscript GPL需要公開原始碼或從 Artifex 取得昂貴的商業授權。
After (IronPDF):
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
' Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY"
步驟 2:更新命名空間匯入
// Before (Ghostscript GPL)
using Ghostscript.NET;
using Ghostscript.NET.Processor;
using Ghostscript.NET.Rasterizer;
// After (IronPDF)
using IronPdf;
// Before (Ghostscript GPL)
using Ghostscript.NET;
using Ghostscript.NET.Processor;
using Ghostscript.NET.Rasterizer;
// After (IronPDF)
using IronPdf;
Imports IronPdf
完整的 API 參考資料
核心類映射
| Ghostscript.NET | IronPDF | 說明 |
|---|---|---|
GhostscriptProcessor |
各種 PdfDocument 方法 |
PDF 處理 |
GhostscriptRasterizer |
PdfDocument.ToBitmap() / RasterizeToImageFiles() |
PDF 至影像 |
GhostscriptVersionInfo |
不適用 (不需要) | DLL 位置 |
GhostscriptStdIO |
不適用(使用例外) | I/O 處理 |
| 流程 + 指令行 | ChromePdfRenderer |
HTML 至 PDF |
指令行切換對應
| Ghostscript GPL 開關 | IronPDF 同等級產品 | 說明 |
|---|---|---|
-dNOPAUSE |
不適用 (不需要) | 頁與頁之間不要停頓 |
-dBATCH |
不適用 (不需要) | 處理完成後退出 |
-dSAFER |
不適用 (預設) | 安全的檔案存取 |
-sDEVICE=pdfwrite |
各種 PDF 方法 | 輸出 PDF |
-sDEVICE=png16m |
ToBitmap() 或 RasterizeToImageFiles() |
PNG 輸出 |
-sOutputFile=X |
SaveAs("X") |
輸出檔案名稱 |
-r300 |
方法中的 DPI 參數 | 解析度 |
-dPDFSETTINGS=/ebook |
CompressImages(quality: 75) |
中等品質 |
-sOwnerPassword=X |
SecuritySettings.OwnerPassword |
業主密碼 |
-sUserPassword=X |
SecuritySettings.UserPassword |
使用者密碼 |
程式碼遷移範例
範例 1:HTML 到 PDF 的轉換
之前 (Ghostscript GPL):
// NuGet: Install-Package Ghostscript.NET
using Ghostscript.NET;
using Ghostscript.NET.Processor;
using System.IO;
using System.Text;
class GhostscriptExample
{
static void Main()
{
// Ghostscript cannot directly convert HTML to PDF
// You need to first convert HTML to PS/EPS using another tool
// then use Ghostscript to convert PS to PDF
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
string psFile = "temp.ps";
string outputPdf = "output.pdf";
// This is a workaround - Ghostscript primarily works with PostScript
GhostscriptProcessor processor = new GhostscriptProcessor();
List<string> switches = new List<string>
{
"-dNOPAUSE",
"-dBATCH",
"-dSAFER",
"-sDEVICE=pdfwrite",
$"-sOutputFile={outputPdf}",
psFile
};
processor.Process(switches.ToArray());
}
}
// NuGet: Install-Package Ghostscript.NET
using Ghostscript.NET;
using Ghostscript.NET.Processor;
using System.IO;
using System.Text;
class GhostscriptExample
{
static void Main()
{
// Ghostscript cannot directly convert HTML to PDF
// You need to first convert HTML to PS/EPS using another tool
// then use Ghostscript to convert PS to PDF
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
string psFile = "temp.ps";
string outputPdf = "output.pdf";
// This is a workaround - Ghostscript primarily works with PostScript
GhostscriptProcessor processor = new GhostscriptProcessor();
List<string> switches = new List<string>
{
"-dNOPAUSE",
"-dBATCH",
"-dSAFER",
"-sDEVICE=pdfwrite",
$"-sOutputFile={outputPdf}",
psFile
};
processor.Process(switches.ToArray());
}
}
Imports Ghostscript.NET
Imports Ghostscript.NET.Processor
Imports System.IO
Imports System.Text
Class GhostscriptExample
Shared Sub Main()
' Ghostscript cannot directly convert HTML to PDF
' You need to first convert HTML to PS/EPS using another tool
' then use Ghostscript to convert PS to PDF
Dim htmlContent As String = "<html><body><h1>Hello World</h1></body></html>"
Dim psFile As String = "temp.ps"
Dim outputPdf As String = "output.pdf"
' This is a workaround - Ghostscript primarily works with PostScript
Dim processor As New GhostscriptProcessor()
Dim switches As New List(Of String) From {
"-dNOPAUSE",
"-dBATCH",
"-dSAFER",
"-sDEVICE=pdfwrite",
$"-sOutputFile={outputPdf}",
psFile
}
processor.Process(switches.ToArray())
End Sub
End Class
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class IronPdfExample
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class IronPdfExample
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Class IronPdfExample
Shared Sub Main()
Dim renderer As New ChromePdfRenderer()
Dim htmlContent As String = "<html><body><h1>Hello World</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("output.pdf")
End Sub
End Class
兩者的差異非常明顯:Ghostscript GPL 完全無法直接將 HTML 轉換成 PDF - 它需要使用外部工具進行 PostScript 的中間轉換。IronPDF的 ChromePdfRenderer 提供直接的 HTML 到 PDF 轉換,並完全支援 CSS3、JavaScript 和現代 Web 標準。 請參閱 HTML to PDF 文件,以瞭解更多渲染選項。
範例 2:PDF 至圖片
之前 (Ghostscript GPL):
// NuGet: Install-Package Ghostscript.NET
using Ghostscript.NET;
using Ghostscript.NET.Rasterizer;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
class GhostscriptExample
{
static void Main()
{
string inputPdf = "input.pdf";
string outputPath = "output";
GhostscriptVersionInfo gvi = new GhostscriptVersionInfo("gsdll64.dll");
using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer())
{
rasterizer.Open(inputPdf, gvi, false);
for (int pageNumber = 1; pageNumber <= rasterizer.PageCount; pageNumber++)
{
Image img = rasterizer.GetPage(300, pageNumber);
img.Save($"{outputPath}_page{pageNumber}.png", ImageFormat.Png);
img.Dispose();
}
}
}
}
// NuGet: Install-Package Ghostscript.NET
using Ghostscript.NET;
using Ghostscript.NET.Rasterizer;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
class GhostscriptExample
{
static void Main()
{
string inputPdf = "input.pdf";
string outputPath = "output";
GhostscriptVersionInfo gvi = new GhostscriptVersionInfo("gsdll64.dll");
using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer())
{
rasterizer.Open(inputPdf, gvi, false);
for (int pageNumber = 1; pageNumber <= rasterizer.PageCount; pageNumber++)
{
Image img = rasterizer.GetPage(300, pageNumber);
img.Save($"{outputPath}_page{pageNumber}.png", ImageFormat.Png);
img.Dispose();
}
}
}
}
Imports Ghostscript.NET
Imports Ghostscript.NET.Rasterizer
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.IO
Class GhostscriptExample
Shared Sub Main()
Dim inputPdf As String = "input.pdf"
Dim outputPath As String = "output"
Dim gvi As New GhostscriptVersionInfo("gsdll64.dll")
Using rasterizer As New GhostscriptRasterizer()
rasterizer.Open(inputPdf, gvi, False)
For pageNumber As Integer = 1 To rasterizer.PageCount
Dim img As Image = rasterizer.GetPage(300, pageNumber)
img.Save($"{outputPath}_page{pageNumber}.png", ImageFormat.Png)
img.Dispose()
Next
End Using
End Sub
End Class
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class IronPdfExample
{
static void Main()
{
var pdf = PdfDocument.FromFile("input.pdf");
var images = pdf.ToBitmap();
for (int i = 0; i < images.Length; i++)
{
images[i].Save($"output_page{i + 1}.png");
}
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class IronPdfExample
{
static void Main()
{
var pdf = PdfDocument.FromFile("input.pdf");
var images = pdf.ToBitmap();
for (int i = 0; i < images.Length; i++)
{
images[i].Save($"output_page{i + 1}.png");
}
}
}
Imports IronPdf
Imports System
Class IronPdfExample
Shared Sub Main()
Dim pdf = PdfDocument.FromFile("input.pdf")
Dim images = pdf.ToBitmap()
For i As Integer = 0 To images.Length - 1
images(i).Save($"output_page{i + 1}.png")
Next
End Sub
End Class
Ghostscript GPL 方法需要找到外部 gsdll64.dll,建立一個 GhostscriptVersionInfo 對象,並使用從 1 開始的頁碼。IronPDF的 ToBitmap() 方法提供了一個簡潔的單行方法,沒有任何外部相依性。 請注意頁面索引的差異:Ghostscript GPL 使用 1-indexed 頁面,而IronPDF則使用 0-indexed 頁面(標準 .NET 慣例)。
範例 3:合併 PDF 檔案
之前 (Ghostscript GPL):
// NuGet: Install-Package Ghostscript.NET
using Ghostscript.NET;
using Ghostscript.NET.Processor;
using System.Collections.Generic;
class GhostscriptExample
{
static void Main()
{
string outputPdf = "merged.pdf";
string[] inputFiles = { "file1.pdf", "file2.pdf", "file3.pdf" };
GhostscriptProcessor processor = new GhostscriptProcessor();
List<string> switches = new List<string>
{
"-dNOPAUSE",
"-dBATCH",
"-dSAFER",
"-sDEVICE=pdfwrite",
$"-sOutputFile={outputPdf}"
};
switches.AddRange(inputFiles);
processor.Process(switches.ToArray());
}
}
// NuGet: Install-Package Ghostscript.NET
using Ghostscript.NET;
using Ghostscript.NET.Processor;
using System.Collections.Generic;
class GhostscriptExample
{
static void Main()
{
string outputPdf = "merged.pdf";
string[] inputFiles = { "file1.pdf", "file2.pdf", "file3.pdf" };
GhostscriptProcessor processor = new GhostscriptProcessor();
List<string> switches = new List<string>
{
"-dNOPAUSE",
"-dBATCH",
"-dSAFER",
"-sDEVICE=pdfwrite",
$"-sOutputFile={outputPdf}"
};
switches.AddRange(inputFiles);
processor.Process(switches.ToArray());
}
}
Imports Ghostscript.NET
Imports Ghostscript.NET.Processor
Imports System.Collections.Generic
Class GhostscriptExample
Shared Sub Main()
Dim outputPdf As String = "merged.pdf"
Dim inputFiles As String() = {"file1.pdf", "file2.pdf", "file3.pdf"}
Dim processor As New GhostscriptProcessor()
Dim switches As New List(Of String) From {
"-dNOPAUSE",
"-dBATCH",
"-dSAFER",
"-sDEVICE=pdfwrite",
$"-sOutputFile={outputPdf}"
}
switches.AddRange(inputFiles)
processor.Process(switches.ToArray())
End Sub
End Class
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using System.Collections.Generic;
class IronPdfExample
{
static void Main()
{
var pdfs = new List<PdfDocument>
{
PdfDocument.FromFile("file1.pdf"),
PdfDocument.FromFile("file2.pdf"),
PdfDocument.FromFile("file3.pdf")
};
var merged = PdfDocument.Merge(pdfs);
merged.SaveAs("merged.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System.Collections.Generic;
class IronPdfExample
{
static void Main()
{
var pdfs = new List<PdfDocument>
{
PdfDocument.FromFile("file1.pdf"),
PdfDocument.FromFile("file2.pdf"),
PdfDocument.FromFile("file3.pdf")
};
var merged = PdfDocument.Merge(pdfs);
merged.SaveAs("merged.pdf");
}
}
Imports IronPdf
Imports System.Collections.Generic
Class IronPdfExample
Shared Sub Main()
Dim pdfs As New List(Of PdfDocument) From {
PdfDocument.FromFile("file1.pdf"),
PdfDocument.FromFile("file2.pdf"),
PdfDocument.FromFile("file3.pdf")
}
Dim merged = PdfDocument.Merge(pdfs)
merged.SaveAs("merged.pdf")
End Sub
End Class
Ghostscript GPL 方法需要記住 switch 語法(-dNOPAUSE, -dBATCH, -sDEVICE=pdfwrite)並將檔案路徑連接成字串陣列。IronPDF的靜態 Merge 方法提供類型安全、支援 IntelliSense 的合併功能,可與正確的 PdfDocument 物件合併。 進一步瞭解 合併與分割 PDF 的相關資訊。
關鍵遷移注意事項
頁面索引轉換
在這次Ghostscript GPL移轉中,最重要的改變之一就是頁面索引的差異:
// Ghostscript GPL: 1-indexed pages
for (int pageNumber = 1; pageNumber <= rasterizer.PageCount; pageNumber++)
{
Image img = rasterizer.GetPage(300, pageNumber);
}
// IronPDF: 0-indexed pages (standard .NET)
for (int i = 0; i < images.Length; i++)
{
images[i].Save($"output_page{i + 1}.png");
}
// Ghostscript GPL: 1-indexed pages
for (int pageNumber = 1; pageNumber <= rasterizer.PageCount; pageNumber++)
{
Image img = rasterizer.GetPage(300, pageNumber);
}
// IronPDF: 0-indexed pages (standard .NET)
for (int i = 0; i < images.Length; i++)
{
images[i].Save($"output_page{i + 1}.png");
}
Option Strict On
' Ghostscript GPL: 1-indexed pages
For pageNumber As Integer = 1 To rasterizer.PageCount
Dim img As Image = rasterizer.GetPage(300, pageNumber)
Next
' IronPDF: 0-indexed pages (standard .NET)
For i As Integer = 0 To images.Length - 1
images(i).Save($"output_page{i + 1}.png")
Next
消除對 AGPL 授權的疑慮
Ghostscript GPL 的 AGPL 授權具有"病毒"特性,在散佈應用程式時需要揭露原始碼。IronPDF的商業授權條款明確,沒有這些要求。
無外部二進位檔案
IronPDF 完全獨立。 移轉後移除這些內容:
gsdll32.dll和gsdll64.dll文件- 從伺服器安裝 Ghostscript GPL
- PATH 環境變數配置
GhostscriptVersionInfo程式碼中的引用
PostScript 檔案
IronPDF 不能直接處理 PostScript (.ps) 檔案。 如果您的工作流程需要 PostScript 處理,請選擇下列其中一種: 1.在IronPDF處理之前使用其他工具將 PostScript 轉換為 PDF 2.將源內容轉換為 HTML,並使用IronPDF的 HTML 渲染功能
效能考量
無流程產生
Ghostscript GPL 操作會產生外部進程,並帶來相關的開銷。IronPDF可在您的 .NET 流程中運行:
// Ghostscript GPL: Process spawning overhead
processor.Process(switches.ToArray()); // Creates new OS process
// IronPDF: In-process execution
var merged = PdfDocument.Merge(pdfs); // Native .NET method call
// Ghostscript GPL: Process spawning overhead
processor.Process(switches.ToArray()); // Creates new OS process
// IronPDF: In-process execution
var merged = PdfDocument.Merge(pdfs); // Native .NET method call
線程安全
IronPDF 在設計上是線程安全的。 多個執行緒可以同時使用 ChromePdfRenderer 和 PdfDocument,而無需擔心同步問題。
遷移清單
預遷移
- 清點程式碼庫中所有Ghostscript GPL的使用情況
- 記錄目前使用的命令列開關
- 識別任何 PostScript 處理(需要特殊處理)
- 審查 AGPL 許可合規性
- 取得IronPDF許可證密鑰
- 在版本控制系統中建立遷移分支
程式碼遷移
- 移除 Ghostscript.NET NuGet 套件:
dotnet remove package Ghostscript.NET - 安裝 IronPdf NuGet 套件:
dotnet add package IronPdf - 移除外部Ghostscript GPL二進位依賴項
- 刪除
GhostscriptVersionInfo和 DLL 引用 - 將
GhostscriptProcessor.Process()轉換為IronPDF方法 - 將
GhostscriptRasterizer轉換為pdf.ToBitmap() - 用 API 呼叫取代命令列開關
- 將錯誤處理方式從解析標準錯誤輸出 (stderr) 改為拋出例外 將以 1 為索引的頁碼轉換為以 0 為索引的頁碼
測試
- 測試 PDF 轉圖像轉換
- 測試 PDF 合併
- 測試頁面擷取
- 測試壓縮質量
- 測試密碼保護
- 驗證輸出品質是否符合預期
- 效能基準關鍵路徑
部署
從伺服器中移除 Ghostscript GPL
- 刪除 PATH 配置
- 從部署中移除
gsdll*.dll文件 - 驗證應用程式在未安裝Ghostscript GPL的情況下是否能正常運作
後遷移
- 移除Ghostscript GPL許可證(如果是商業用途)
- 更新文件
- 訓練團隊使用IronPDFAPI
- 監控生產過程,發現任何問題

