跳過到頁腳內容
遷移指南

如何在 C# 中從 DinkToPdf 轉移到 IronPDF

DinkToPdf 包覆了 wkhtmltopdf,繼承了其所有的安全漏洞和技術限制。 了解這些問題對評估移轉的迫切性至關重要。

關鍵安全問題

DinkToPdf 繼承了 wkhtmltopdf 中未修補的重要安全漏洞:

  1. CVE-2022-35583 (SSRF):伺服器端請求偽造漏洞,允許攻擊者存取內部網路資源 2.已棄用項目: wkhtmltopdf 自 2020 年以來一直未維護。 3.不提供安全修補程式:已知漏洞將永遠不會修復。

技術問題

問題 影響力
線程安全 在生產中,SynchronizedConverter 在並發負載下仍然會當機
原生二進位 使用特定平台的 libwkhtmltox 二進位檔進行複雜部署
CSS 限制 不支援 Flexbox、Grid 或現代 CSS
JavaScript 執行不一致、超時
渲染 過時的 WebKit 引擎 (約 2015 年)
維護 最後更新時間:2018

架構比較

範疇 DinkToPdf IronPDF
安全性 CVE-2022-35583 (SSRF),未修補漏洞 無已知漏洞
渲染引擎 過時的 WebKit (2015) 現代 Chromium
線程安全 並行使用中的當機 完全線程安全
本機依賴性 特定平台的二進位檔 純 NuGet 套件
CSS 支援 無 Flexbox/Grid 完整的 CSS3
JavaScript 有限、不一致 支援
維護 被遺棄 (2018) 積極維護

功能對比

特點 DinkToPdf IronPDF
HTML 至 PDF ✅(過時的引擎) ✅ (Chromium)
URL 至 PDF
自訂頁邊
頁首/頁尾 ✅(有限) ✅ (完整 HTML)
CSS3 ❌ 有限公司 ✅ 全文
Flexbox/Grid
JavaScript ⚠️ 有限公司 ✅ 全文
PDF 操作
表格填寫
數位簽名
加密
水印
合併/分割

遷移前的準備工作

先決條件

確保您的環境符合這些要求:

  • .NET Framework 4.6.2+ 或 .NET Core 3.1 / .NET 5-9
  • Visual Studio 2019+ 或具有 C# 擴充功能的 VS Code
  • NuGet 套件管理員存取權限 -IronPDF授權金鑰 (可於 ironpdf.com 網站免費試用)

審核DinkToPdf使用情況

在您的解決方案目錄中執行這些指令,以識別所有DinkToPdf參考資料:

# Find allDinkToPdfusages in your codebase
grep -r "using DinkToPdf" --include="*.cs" .
grep -r "SynchronizedConverter\|HtmlToPdfDocument\|ObjectSettings" --include="*.cs" .

# Find NuGet package references
grep -r "DinkToPdf" --include="*.csproj" .

# Find wkhtmltopdf binaries
find . -name "libwkhtmltox*"
# Find allDinkToPdfusages in your codebase
grep -r "using DinkToPdf" --include="*.cs" .
grep -r "SynchronizedConverter\|HtmlToPdfDocument\|ObjectSettings" --include="*.cs" .

# Find NuGet package references
grep -r "DinkToPdf" --include="*.csproj" .

# Find wkhtmltopdf binaries
find . -name "libwkhtmltox*"
SHELL

可預期的重大變更

變更 DinkToPdf IronPDF 影響力
轉換器 SynchronizedConverter(new PdfTools()) ChromePdfRenderer 更簡單的實體化
文件 HtmlToPdfDocument 直接方法呼叫 無文件物件
設定 GlobalSettings + ObjectSettings RenderingOptions 單一選項物件
返回類型 byte[] PdfDocument 更強大的物件
二進制 libwkhtmltox.dll/so 無(管理) 移除原生檔案
線程安全 SynchronizedConverter 必填 預設的線程安全 簡化程式碼
DI 需要單件 任何終生 靈活

逐步遷移的過程

步驟 1:更新 NuGet 套件

移除DinkToPdf並安裝 IronPDF:

# Remove DinkToPdf
dotnet remove package DinkToPdf

# Install IronPDF
dotnet add package IronPdf
# Remove DinkToPdf
dotnet remove package DinkToPdf

# Install IronPDF
dotnet add package IronPdf
SHELL

步驟 2:移除原生二進位檔案

從您的專案中刪除這些特定平台的檔案:

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

IronPDF 沒有本機相依性 - 所有東西都是管理代碼。

步驟 3:更新命名空間參考資料

用IronPDF取代DinkToPdf命名空間:

// Remove these
using DinkToPdf;
using DinkToPdf.Contracts;

// Add this
using IronPdf;
// Remove these
using DinkToPdf;
using DinkToPdf.Contracts;

// Add this
using IronPdf;
Imports IronPdf
$vbLabelText   $csharpLabel

步驟 4:配置授權

// Add at application startup (Program.cs or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup (Program.vb or Global.asax)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

完整的 API 遷移參考。

核心類映射

DinkToPdf IronPDF
SynchronizedConverter ChromePdfRenderer
BasicConverter ChromePdfRenderer
PdfTools 不需要
HtmlToPdfDocument 不需要
GlobalSettings RenderingOptions
ObjectSettings RenderingOptions
MarginSettings 個別邊界屬性

全局設定映射

DinkToPdf 全局設定 IronPDF 同等級產品
ColorMode = ColorMode.Color 預設 (總是顏色)
Orientation = Orientation.Portrait PaperOrientation = PdfPaperOrientation.Portrait
Orientation = Orientation.Landscape PaperOrientation = PdfPaperOrientation.Landscape
PaperSize = PaperKind.A4 PaperSize = PdfPaperSize.A4
Margins = new MarginSettings() 個別邊界屬性

邊界設定映射

DinkToPdf 的邊界 IronPDF 同等級產品
Margins.Top = 10 MarginTop = 10
Margins.Bottom = 10 MarginBottom = 10
Margins.Left = 15 MarginLeft = 15
Margins.Right = 15 MarginRight = 15

程式碼遷移範例

基本 HTML 轉 PDF

基本轉換展示了從DinkToPdf冗長的配置到IronPDF精簡 API 的大幅簡化。

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 = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        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 = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter = New SynchronizedConverter(New PdfTools())
        Dim doc = New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = {
                New ObjectSettings() With {
                    .HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>",
                    .WebSettings = New WebSettings() With {
                        .DefaultEncoding = "utf-8"
                    }
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("output.pdf", pdf)
    End Sub
End Module
$vbLabelText   $csharpLabel

IronPDF 實作:

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
        pdf.SaveAs("output.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>")
        pdf.SaveAs("output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

IronPDF 可將 20 行的DinkToPdf設定縮減為 4 行。 沒有 SynchronizedConverter,沒有 PdfTools,沒有 HtmlToPdfDocument,沒有 ObjectSettings——只需渲染並保存。 如需更多選項,請參閱 HTML to PDF 文件

URL 轉 PDF

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);
    }
}
Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter = New SynchronizedConverter(New PdfTools())
        Dim doc = New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = New List(Of ObjectSettings) From {
                New ObjectSettings() With {
                    .Page = "https://www.example.com"
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("webpage.pdf", pdf)
    End Sub
End Module
$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");
    }
}
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
$vbLabelText   $csharpLabel

IronPDF 的 RenderUrlAsPdf 將嵌套的 ObjectSettings.Page 配置替換為直接方法呼叫。 如需更多選項,請參閱 URL 至 PDF 文件

具有橫向和邊界的自訂設定

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.A4,
                Margins = new MarginSettings { Top = 10, Bottom = 10, Left = 15, Right = 15 }
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("custom.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.A4,
                Margins = new MarginSettings { Top = 10, Bottom = 10, Left = 15, Right = 15 }
            },
            Objects = {
                new ObjectSettings() {
                    HtmlContent = "<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("custom.pdf", pdf);
    }
}
Imports DinkToPdf
Imports DinkToPdf.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter = New SynchronizedConverter(New PdfTools())
        Dim doc = New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Landscape,
                .PaperSize = PaperKind.A4,
                .Margins = New MarginSettings() With {
                    .Top = 10,
                    .Bottom = 10,
                    .Left = 15,
                    .Right = 15
                }
            },
            .Objects = {
                New ObjectSettings() With {
                    .HtmlContent = "<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>",
                    .WebSettings = New WebSettings() With {
                        .DefaultEncoding = "utf-8"
                    }
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("custom.pdf", pdf)
    End Sub
End Module
$vbLabelText   $csharpLabel

IronPDF 實作:

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 15;
        renderer.RenderingOptions.MarginRight = 15;

        var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>");
        pdf.SaveAs("custom.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 15;
        renderer.RenderingOptions.MarginRight = 15;

        var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>");
        pdf.SaveAs("custom.pdf");
    }
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System

Module Program
    Sub Main()
        Dim renderer As New ChromePdfRenderer()
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
        renderer.RenderingOptions.MarginTop = 10
        renderer.RenderingOptions.MarginBottom = 10
        renderer.RenderingOptions.MarginLeft = 15
        renderer.RenderingOptions.MarginRight = 15

        Dim pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>Landscape orientation with custom margins.</p>")
        pdf.SaveAs("custom.pdf")
    End Sub
End Module
$vbLabelText   $csharpLabel

IronPDF 的 RenderingOptions 用統一、流暢的 API 取代了 GlobalSettingsMarginSettings。 如需更多組態選項,請參閱 渲染選項說明文件

關鍵遷移注意事項

移除原生二進位檔案

最重要的清理步驟是移除 wkhtmltopdf 原生二進位檔案。IronPDF沒有本機相依性:

# Delete native binaries
rm libwkhtmltox.* 2>/dev/null
# Delete native binaries
rm libwkhtmltox.* 2>/dev/null
SHELL

不需要單件。

DinkToPdf 的 SynchronizedConverter 必須註冊為單例以避免崩潰。IronPDF的 ChromePdfRenderer 在任何依賴注入生命週期內都是線程安全的:

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

//IronPDF- any lifetime works
services.AddScoped<ChromePdfRenderer>();
// Or just create inline:
var renderer = new ChromePdfRenderer();
//DinkToPdf- MUST be singleton
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));

//IronPDF- any lifetime works
services.AddScoped<ChromePdfRenderer>();
// Or just create inline:
var renderer = new ChromePdfRenderer();
' DinkToPdf- MUST be singleton
services.AddSingleton(GetType(IConverter), New SynchronizedConverter(New PdfTools()))

' IronPDF- any lifetime works
services.AddScoped(Of ChromePdfRenderer)()
' Or just create inline:
Dim renderer As New ChromePdfRenderer()
$vbLabelText   $csharpLabel

Richer 返回類型

DinkToPdf 回傳 byte[]。IronPDF回傳 PdfDocument,並具備操作功能:

//DinkToPdfreturns byte[]
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
return File(pdf, "application/pdf");

//IronPDFreturns PdfDocument
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
return File(pdf.BinaryData, "application/pdf");
//DinkToPdfreturns byte[]
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
return File(pdf, "application/pdf");

//IronPDFreturns PdfDocument
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
return File(pdf.BinaryData, "application/pdf");
' DinkToPdf returns byte()
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("output.pdf", pdf)
Return File(pdf, "application/pdf")

' IronPDF returns PdfDocument
Dim pdfDocument = renderer.RenderHtmlAsPdf(html)
pdfDocument.SaveAs("output.pdf")
Return File(pdfDocument.BinaryData, "application/pdf")
$vbLabelText   $csharpLabel

完全支援 CSS3

在DinkToPdf中失效的現代佈局在IronPDF中可以完美運作:

//DinkToPdf- doesn't work (wkhtmltopdf uses 2015 WebKit)
var html = "<div style='display: flex;'>...</div>";  // Broken!

//IronPDF- full support (modern Chromium)
var html = @"
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>";
var pdf = renderer.RenderHtmlAsPdf(html);  // Works!
//DinkToPdf- doesn't work (wkhtmltopdf uses 2015 WebKit)
var html = "<div style='display: flex;'>...</div>";  // Broken!

//IronPDF- full support (modern Chromium)
var html = @"
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>";
var pdf = renderer.RenderHtmlAsPdf(html);  // Works!
' DinkToPdf- doesn't work (wkhtmltopdf uses 2015 WebKit)
Dim html As String = "<div style='display: flex;'>...</div>"  ' Broken!

' IronPDF- full support (modern Chromium)
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!
$vbLabelText   $csharpLabel

遷移後檢查清單

完成程式碼遷移後,請驗證下列事項:

執行所有單元測試以驗證 PDF 產生功能是否正常。

  • 測試多執行緒場景(這些場景在使用DinkToPdf時崩潰了)
  • 比較PDF輸出品質(IronPDF的Chromium渲染效果較好)
  • 驗證 CSS 渲染效果(Flexbox/Grid 現在正常運作)
  • 測試JavaScript執行(使用IronPDF可確保可靠性)
  • 更新 CI/CD 管線,移除 wkhtmltopdf 安裝
  • 驗證安全掃描通過(不再有 CVE-2022-35583 標誌)
  • 從 Docker/部署腳本移除原生二進位部署

讓您的 PDF 基礎架構面向未來

由於 .NET 10 即將推出,而 C# 14 也將引進新的語言功能,因此選擇積極維護的 PDF 函式庫可確保長期的相容性。IronPDF的現代 Chromium 引擎會定期更新,而DinkToPdf棄用的 wkhtmltopdf 仍停留在 2015 年的功能 - 這種差距會不斷擴大,因為網頁標準會在 2025 年和 2026 年不斷演進。

其他資源


從DinkToPdf轉移到IronPDF可消除重要的安全漏洞 (CVE-2022-35583)、線程安全崩潰、原生二進位部署的複雜性,以及過時的 CSS 渲染。 過渡到現代 Chromium 引擎可提供完整的CSS3支援、可靠的JavaScript執行,以及積極維護的程式庫所帶來的安心感。

Curtis Chau
技術作家

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

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

鋼鐵支援團隊

我們每週 5 天,每天 24 小時在線上。
聊天
電子郵件
打電話給我