從Accusoft BarcodeXpress遷移至 IronBarcode
這次遷移中的大部分工作是刪除。 雙密鑰授權系統 —— SetSolutionKey 和 SetOEMLicenseKey 用於運行時 —— 全部消失。 實際的條碼操作(讀取影像,在檔案中寫入條碼)轉換為更短的IronBarcode等效操作。 如果您的程式碼庫中有一個 BarcodeService 類別包裹 BarcodeXpress,則授權程式碼常常是其中的一大部分。 遷移後,這個類別縮小了。
為何從Accusoft BarcodeXpress遷移
從 BarcodeXpress 遷移的團隊報告以下觸發因素:
評估模式阻礙準確基準測試: 沒有有效的 OEM/運行時密鑰,BarcodeXpress 在解碼結果中蓋上 "UNLICENSED accusoft.com" 字樣,並在生成的 2D 條碼上應用相同印章。 預購精確度測試在真實文件上產生這樣的水印輸出,因此在購買之前,您無法驗證該庫是否正確讀取實際掃描型別。
雙鑰授權增加操作開銷: BarcodeXpress 將 SDK 授權(SetSolutionName 和 SetSolutionKey)與 OEM/運行時授權(SetOEMLicenseKey)分開。 CI/CD 管道、Docker 容器和容器協調器各自需要將兩個密鑰系統作為單獨的秘密進行管理。 缺失或無效的運行時密鑰導致水印輸出,而不是引發錯誤,從而建立了一種在自動化測試中可能通過非空結果檢查的失敗模式。
任何生產部署至少需要五個運行時授權: 即使是單伺服器部署也需要購買至少五個運行時授權。 在運行一個生產伺服器和一個預備伺服器的團隊,即使是實際使用,也必須至少支付十個運行時授權的費用。
40 PPM 標準版上限: 標準版將處理速度限制為每分鐘 40 頁。 在這個速度下,處理 100,000 份文件大約需要 41 小時。 要刪除上限需要升級到專業版,這會在開發者席位費用之外再增加費用。
無原生 PDF 支援: 必須使用單獨的庫將 PDF 文件渲染到影像,然後 BarcodeXpress 才能讀取它們。 此外部相依性增加了第二授權費用、轉換步驟以及保持渲染後的頁面影像所需的額外記憶體壓力。
執行緒安全需要實例隔離: BarcodeXpress 的 reader 物件有狀態,且不適合並發存取。 並行批量處理需要每個執行緒一個完全初始化的 BarcodeXpress 實例,在每個執行緒上下文中重複完整的雙層授權初始化。
基本問題
BarcodeXpress 在讀取任何條碼之前需要多步初始化、位圖載入以及 BarcodeType[] 配置:
using var bitmap = new Bitmap(imagePath);
var barcodeXpress = new BarcodeXpress(".");
barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
barcodeXpress.Licensing.SetOEMLicenseKey("2.0.OEMLicenseStringFromAccusoft...");
barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
};
Result[] results = barcodeXpress.reader.Analyze(bitmap);
var value = results.FirstOrDefault()?.BarcodeValue;Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk
Using bitmap As New Bitmap(imagePath)
Dim barcodeXpress = New BarcodeXpress(".")
barcodeXpress.Licensing.SetSolutionName("AcmeCorp")
barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4)
barcodeXpress.Licensing.SetOEMLicenseKey("2.0.OEMLicenseStringFromAccusoft...")
barcodeXpress.Reader.BarcodeTypes = New BarcodeType() {
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
}
Dim results As Result() = barcodeXpress.Reader.Analyze(bitmap)
Dim value = results.FirstOrDefault()?.BarcodeValue
End UsingIronBarcode 用一個靜態調用替換了這整個塊:
var value = BarcodeReader.Read(imagePath).First().Value;Dim value = BarcodeReader.Read(imagePath).First().ValueIronBarcode vs Accusoft BarcodeXpress:功能比較
| 功能 | Accusoft BarcodeXpress | IronBarcode |
|---|---|---|
| 授權模式 | SDK 密鑰 + OEM/運行時密鑰(單獨購買) | 單一永久密鑰 |
| 最少運行時授權 | 5(即使是 1 伺服器) | 無運行時授權概念 |
| 評估模式 | 解碼值和生成的 2D 條碼被印上 "UNLICENSED accusoft.com" | 返回完整值; 僅在生成的輸出上水印 |
| 吞吐量限制 | 40 PPM(標準版) | 在任何層級都無限制 |
| 格式自動檢測 | 手動——必須將 BarcodeType[] 陣列指定給 BarcodeTypes | 自動跨所有支援的格式 |
| PDF 支援 | 需要單獨的庫來將頁面呈現為位圖 | 原生——BarcodeReader.Read("doc.pdf") |
| API 風格 | 基於實例; 位圖輸入; 屬性/方法配置 | 靜態工廠方法,流暢的 API |
| 執行緒安全 | 每個執行緒需要實例 | 無狀態靜態方法——執行緒安全 |
| Docker 授權配置 | 授權檔案裝載或授權伺服器 | 單一環境變數 |
| CI/CD 機密要求 | SDK 密鑰對 + OEM/運行時密鑰 | 一個機密 |
| .NET Framework / .NET Core | 單獨的包:Accusoft.BarcodeXpress.Net 和 Accusoft.BarcodeXpress.NetCore | 單一 IronBarcode 包(.NET Framework 4.6.2+, .NET Core 3.1+, .NET 5–8) |
| Linux/macOS | 是的(通過 .NetCore 包) | 是的——Windows x64/x86,Linux x64,macOS x64/ARM |
| 帶標誌的 QR 碼 | 需要手動 GDI+ 覆蓋 | 內建 AddBrandLogo("logo.png") |
| 價格入門點 | $1,960+ SDK + 最少 5 個運行時授權 | $999 永久(Lite,1 開發者) |
| 永久授權 | 不標準——聯絡銷售 | 是的,所有層級 |
快速入門:從Accusoft BarcodeXpress遷移到 IronBarcode
步驟 1:替換 NuGet 包
dotnet remove package Accusoft.BarcodeXpress.NetCore
dotnet add package IronBarcode
步驟 2:更新命名空間
// Remove
using Accusoft.BarcodeXpressSdk;
// Add
using IronBarCode;Imports IronBarCode步驟 3:初始化授權
在 Startup.cs 或您的相依注入配置中,僅在應用程式啟動時新增一次授權初始化:
// Add once at application startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";' Add once at application startup
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"在生產中,從環境變數或您的機密管理器中讀取密鑰:
IronBarCode.License.LicenseKey =
Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE")
?? throw new InvalidOperationException("IronBarcode license key not configured");Imports IronBarCode
Imports System
License.LicenseKey = If(Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE"), Throw New InvalidOperationException("IronBarcode license key not configured"))沒有 SetSolutionKey,沒有 SetOEMLicenseKey,沒有每伺服器運行時啟用。 這是完整的授權設置。
程式碼遷移範例
授權初始化
BarcodeXpress 方法:
using Accusoft.BarcodeXpressSdk;
public class BarcodeService
{
private readonly BarcodeXpress _barcodeXpress;
public BarcodeService()
{
// Constructor takes the path containing the Barcode Xpress runtime files.
_barcodeXpress = new BarcodeXpress(".");
// SDK license
_barcodeXpress.Licensing.SetSolutionName("AcmeCorp");
_barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4);
// OEM/runtime license — separate purchase, minimum 5 licenses required.
// Without this call, decoded values and generated 2D barcodes are
// stamped with " UNLICENSED accusoft.com ".
_barcodeXpress.Licensing.SetOEMLicenseKey(
"2.0.OEMLicenseStringFromAccusoft...");
}
}Imports Accusoft.BarcodeXpressSdk
Public Class BarcodeService
Private ReadOnly _barcodeXpress As BarcodeXpress
Public Sub New()
' Constructor takes the path containing the Barcode Xpress runtime files.
_barcodeXpress = New BarcodeXpress(".")
' SDK license
_barcodeXpress.Licensing.SetSolutionName("AcmeCorp")
_barcodeXpress.Licensing.SetSolutionKey(1, 2, 3, 4)
' OEM/runtime license — separate purchase, minimum 5 licenses required.
' Without this call, decoded values and generated 2D barcodes are
' stamped with " UNLICENSED accusoft.com ".
_barcodeXpress.Licensing.SetOEMLicenseKey("2.0.OEMLicenseStringFromAccusoft...")
End Sub
End ClassIronBarcode 方法:
using IronBarCode;
// In Program.cs
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE");
// BarcodeService no longer needs a constructor or any license management
public class BarcodeService
{
// Ready to use — no initialization needed
}Imports IronBarCode
' In Program.vb
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE")
' BarcodeService no longer needs a constructor or any license management
Public Class BarcodeService
' Ready to use — no initialization needed
End ClassBarcodeXpress 建構函式僅存在於管理兩個授權密鑰系統和運行時路徑。IronBarcode在應用程式啟動時用一行代替它。BarcodeService 類別根本不需要建構函式。
條碼閱讀
BarcodeXpress 方法:
using System.Drawing;
using Accusoft.BarcodeXpressSdk;
public string ReadFirstBarcode(string imagePath)
{
// Analyze takes a System.Drawing.Bitmap; the SDK does not read PDFs directly.
using var bitmap = new Bitmap(imagePath);
_barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
};
Result[] results = _barcodeXpress.reader.Analyze(bitmap);
return results.FirstOrDefault()?.BarcodeValue;
}Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk
Public Function ReadFirstBarcode(imagePath As String) As String
' Analyze takes a System.Drawing.Bitmap; the SDK does not read PDFs directly.
Using bitmap As New Bitmap(imagePath)
_barcodeXpress.reader.BarcodeTypes = New BarcodeType() {
BarcodeType.Code128Barcode,
BarcodeType.DataMatrixBarcode,
BarcodeType.QRCodeBarcode
}
Dim results As Result() = _barcodeXpress.reader.Analyze(bitmap)
Return results.FirstOrDefault()?.BarcodeValue
End Using
End FunctionIronBarcode 方法:
using IronBarCode;
public string ReadFirstBarcode(string imagePath)
{
var results = BarcodeReader.Read(imagePath);
return results.First().Value;
}Imports IronBarCode
Public Function ReadFirstBarcode(imagePath As String) As String
Dim results = BarcodeReader.Read(imagePath)
Return results.First().Value
End FunctionBarcodeTypes 陣列篩選器和 new Bitmap(...) 載入步驟都消失了。IronBarcode自動檢測所有支援的符號格式,並直接接受檔案路徑。 如果供應商從 Code 128 切換到 DataMatrix,IronBarcode 無需任何程式碼更改即可繼續運行。 結果屬性名稱也會改變:BarcodeValue 變成 BarcodeType 變成 Format。 整個方案的搜尋和替換即可處理這兩個替換。
從一個影像讀取多個條碼
BarcodeXpress 方法:
using System.Drawing;
using Accusoft.BarcodeXpressSdk;
public IReadOnlyList<string> ReadAllBarcodes(string imagePath)
{
using var bitmap = new Bitmap(imagePath);
_barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
};
Result[] results = _barcodeXpress.reader.Analyze(bitmap);
return results.Select(r => r.BarcodeValue).ToList();
}Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk
Public Function ReadAllBarcodes(imagePath As String) As IReadOnlyList(Of String)
Using bitmap As New Bitmap(imagePath)
_barcodeXpress.reader.BarcodeTypes = New BarcodeType() {
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
}
Dim results As Result() = _barcodeXpress.reader.Analyze(bitmap)
Return results.Select(Function(r) r.BarcodeValue).ToList()
End Using
End FunctionIronBarcode 方法:
using IronBarCode;
public IReadOnlyList<string> ReadAllBarcodes(string imagePath)
{
var options = new BarcodeReaderOptions { ExpectMultipleBarcodes = true };
var results = BarcodeReader.Read(imagePath, options);
return results.Select(r => r.Value).ToList();
}Imports IronBarCode
Public Function ReadAllBarcodes(imagePath As String) As IReadOnlyList(Of String)
Dim options As New BarcodeReaderOptions With {.ExpectMultipleBarcodes = True}
Dim results = BarcodeReader.Read(imagePath, options)
Return results.Select(Function(r) r.Value).ToList()
End FunctionExpectMultipleBarcodes 告訴IronBarcode在第一次匹配後繼續掃描,這對於具有多個不同區域條碼的文件非常有用。 有關讀取選項的更多詳情,請參閱 IronBarcode 讀取文件。
批量處理
BarcodeXpress 是基於實例的,其 reader 物件有狀態,因此並行批量處理需要每個執行緒一個實例,並在每個執行緒中重複完整的雙層授權初始化。IronBarcode的靜態方法是無狀態的,所以 Parallel.ForEach 不需要實例管理。
BarcodeXpress 方法:
using System.Collections.Generic;
using System.Drawing;
using Accusoft.BarcodeXpressSdk;
public Dictionary<string, string> ProcessBatch(IEnumerable<string> imagePaths)
{
var results = new Dictionary<string, string>();
foreach (var path in imagePaths)
{
using var bitmap = new Bitmap(path);
_barcodeXpress.reader.BarcodeTypes = new[]
{
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
};
Result[] barcodes = _barcodeXpress.reader.Analyze(bitmap);
if (barcodes.Length > 0)
results[path] = barcodes[0].BarcodeValue;
}
return results;
}Imports System.Collections.Generic
Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk
Public Function ProcessBatch(imagePaths As IEnumerable(Of String)) As Dictionary(Of String, String)
Dim results As New Dictionary(Of String, String)()
For Each path In imagePaths
Using bitmap As New Bitmap(path)
_barcodeXpress.reader.BarcodeTypes = New BarcodeType() {
BarcodeType.Code128Barcode,
BarcodeType.QRCodeBarcode
}
Dim barcodes As Result() = _barcodeXpress.reader.Analyze(bitmap)
If barcodes.Length > 0 Then
results(path) = barcodes(0).BarcodeValue
End If
End Using
Next
Return results
End FunctionIronBarcode 方法:
using IronBarCode;
using System.Collections.Concurrent;
using System.Threading.Tasks;
public Dictionary<string, string> ProcessBatch(string[] imagePaths)
{
var results = new ConcurrentDictionary<string, string>();
Parallel.ForEach(imagePaths, file =>
{
var r = BarcodeReader.Read(file);
var first = r.FirstOrDefault();
if (first != null)
results[file] = first.Value;
});
return new Dictionary<string, string>(results);
}Imports IronBarCode
Imports System.Collections.Concurrent
Imports System.Threading.Tasks
Public Function ProcessBatch(imagePaths As String()) As Dictionary(Of String, String)
Dim results = New ConcurrentDictionary(Of String, String)()
Parallel.ForEach(imagePaths, Sub(file)
Dim r = BarcodeReader.Read(file)
Dim first = r.FirstOrDefault()
If first IsNot Nothing Then
results(file) = first.Value
End If
End Sub)
Return New Dictionary(Of String, String)(results)
End Function如果 BarcodeXpress 標準版的每分鐘 40 頁上限導致您新增速率限制處理程式碼 — 在每 40 組之間保持休眠、追蹤按分鐘計算或加入延遲 — 則應完全刪除該程式碼。IronBarcode沒有吞吐量上限。
新增 PDF 支援
BarcodeXpress 無法直接從 PDF 文件讀取條碼。 通常的解決方法是新增獨立的 PDF 渲染庫,將每個頁面渲染到記憶體中的影像,然後一次傳遞這些影像到條碼閱讀器。
BarcodeXpress 方法:
// Requires a separate PDF library (not shown — varies by team choice)
// Pattern: render each PDF page to a Bitmap, then pass it to Analyze.
foreach (Bitmap pageBitmap in pdfRenderer.RenderPages("document.pdf"))
{
using (pageBitmap)
{
_barcodeXpress.reader.BarcodeTypes = Enum.GetValues(typeof(BarcodeType));
Result[] barcodes = _barcodeXpress.reader.Analyze(pageBitmap);
// ... collect results
}
}Imports System
Imports System.Drawing
' Requires a separate PDF library (not shown — varies by team choice)
' Pattern: render each PDF page to a Bitmap, then pass it to Analyze.
For Each pageBitmap As Bitmap In pdfRenderer.RenderPages("document.pdf")
Using pageBitmap
_barcodeXpress.reader.BarcodeTypes = [Enum].GetValues(GetType(BarcodeType))
Dim barcodes As Result() = _barcodeXpress.reader.Analyze(pageBitmap)
' ... collect results
End Using
NextIronBarcode 方法:
using IronBarCode;
// One call — no rendering step, no external dependency
var results = BarcodeReader.Read("document.pdf");
foreach (var barcode in results)
{
Console.WriteLine($"Page {barcode.PageNumber}: [{barcode.Format}] {barcode.Value}");
}Imports IronBarCode
' One call — no rendering step, no external dependency
Dim results = BarcodeReader.Read("document.pdf")
For Each barcode In results
Console.WriteLine($"Page {barcode.PageNumber}: [{barcode.Format}] {barcode.Value}")
Next如果 itext7 或任何其他 PDF 庫僅僅為了支持 BarcodeXpress 閱讀工作流而新增,可以在遷移後予以刪除。 如需更多選項,包括頁面範圍選擇,請參閱 IronBarcode PDF 讀取指南。
條碼生成
BarcodeXpress 方法:
using System.Drawing;
using Accusoft.BarcodeXpressSdk;
public void GenerateBarcode(string data, string outputPath)
{
_barcodeXpress.writer.BarcodeType = BarcodeType.Code128Barcode;
_barcodeXpress.writer.BarcodeValue = data;
// CreateBitmap returns a System.Drawing.Bitmap; persist via Bitmap.Save.
using Bitmap bitmap = _barcodeXpress.writer.CreateBitmap();
bitmap.Save(outputPath);
}Imports System.Drawing
Imports Accusoft.BarcodeXpressSdk
Public Sub GenerateBarcode(data As String, outputPath As String)
_barcodeXpress.writer.BarcodeType = BarcodeType.Code128Barcode
_barcodeXpress.writer.BarcodeValue = data
' CreateBitmap returns a System.Drawing.Bitmap; persist via Bitmap.Save.
Using bitmap As Bitmap = _barcodeXpress.writer.CreateBitmap()
bitmap.Save(outputPath)
End Using
End SubIronBarcode 方法:
using IronBarCode;
public void GenerateBarcode(string data, string outputPath)
{
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ResizeTo(400, 100)
.SaveAsPng(outputPath);
}Imports IronBarCode
Public Sub GenerateBarcode(data As String, outputPath As String)
BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128) _
.ResizeTo(400, 100) _
.SaveAsPng(outputPath)
End Sub流暢鏈取代了屬性分配、CreateBitmap 調用和 Bitmap.Save 步驟。要獲取條碼作為二進制資料以儲存在資料庫或 API 中返回:
byte[] pngBytes = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ToPngBinaryData();Dim pngBytes As Byte() = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128).ToPngBinaryData()QR 碼生成
BarcodeXpress 方法:
_barcodeXpress.writer.BarcodeType = BarcodeType.QRCodeBarcode;
_barcodeXpress.writer.BarcodeValue = data;
using Bitmap bitmap = _barcodeXpress.writer.CreateBitmap();
bitmap.Save("qr.png");
// Logo overlay required manual GDI+ drawing on the returned BitmapImports System.Drawing
_barcodeXpress.writer.BarcodeType = BarcodeType.QRCodeBarcode
_barcodeXpress.writer.BarcodeValue = data
Using bitmap As Bitmap = _barcodeXpress.writer.CreateBitmap()
bitmap.Save("qr.png")
' Logo overlay required manual GDI+ drawing on the returned Bitmap
End UsingIronBarcode 方法:
using IronBarCode;
using IronSoftware.Drawing;
// Simple QR
QRCodeWriter.CreateQrCode("https://example.com", 500)
.SaveAsPng("qr.png");
// With branded logo
QRCodeWriter.CreateQrCode("https://example.com", 500)
.AddBrandLogo("logo.png")
.SaveAsPng("qr-branded.png");
// With high error correction (for logo overlays)
QRCodeWriter.CreateQrCode(
"https://example.com",
500,
QRCodeWriter.QrErrorCorrectionLevel.Highest)
.AddBrandLogo("logo.png")
.SaveAsPng("qr-branded-high-ecc.png");
// Colored QR code
QRCodeWriter.CreateQrCode("https://example.com", 300)
.ChangeBarCodeColor(Color.DarkBlue)
.SaveAsPng("qr-colored.png");Imports IronBarCode
Imports IronSoftware.Drawing
' Simple QR
QRCodeWriter.CreateQrCode("https://example.com", 500) _
.SaveAsPng("qr.png")
' With branded logo
QRCodeWriter.CreateQrCode("https://example.com", 500) _
.AddBrandLogo("logo.png") _
.SaveAsPng("qr-branded.png")
' With high error correction (for logo overlays)
QRCodeWriter.CreateQrCode( _
"https://example.com", _
500, _
QRCodeWriter.QrErrorCorrectionLevel.Highest) _
.AddBrandLogo("logo.png") _
.SaveAsPng("qr-branded-high-ecc.png")
' Colored QR code
QRCodeWriter.CreateQrCode("https://example.com", 300) _
.ChangeBarCodeColor(Color.DarkBlue) _
.SaveAsPng("qr-colored.png")商標嵌入、錯誤修正級別和顏色自定義都內建在流暢的 API 中。 BarcodeXpress 需要在最初檔案寫入後手動 GDI+ 繪製以獲得這些功能中的任何一個。 更多的 QR 碼選項,請參閱 QR 碼生成指南。
Accusoft BarcodeXpress API 到IronBarcode映射參考
| Accusoft BarcodeXpress | IronBarcode |
|---|---|
new BarcodeXpress(".") | 靜態方法——無需實例 |
Licensing.SetSolutionName("...") | IronBarCode.License.LicenseKey = "key" |
Licensing.SetSolutionKey(a, b, c, d) | (removed — not needed) |
Licensing.SetOEMLicenseKey(string) | (removed — no OEM/runtime key concept) |
new Bitmap(path) + reader.Analyze(bitmap) | BarcodeReader.Read(path) |
reader.BarcodeTypes = new[] { BarcodeType.Code128Barcode, ... } | (removed — auto-detection handles all formats) |
result.BarcodeValue | result.Value |
result.BarcodeType | result.Format |
writer.BarcodeType = BarcodeType.Code128Barcode | BarcodeWriter.CreateBarcode("data", BarcodeEncoding.Code128) |
writer.BarcodeValue = "data" | (first argument to CreateBarcode) |
writer.CreateBitmap() + bitmap.Save(path) | .SaveAsPng(path) |
writer.BarcodeType = BarcodeType.QRCodeBarcode | QRCodeWriter.CreateQrCode(data, size) |
| 40 PPM 標準限制 | 在任何層級都無吞吐量限制 |
常見遷移問題及解決方案
問題 1:屬性名稱編譯錯誤
BarcodeXpress: 結果物件暴露 BarcodeValue 和 BarcodeType,而這在IronBarcode中不存在。
解決方案: 在建置之前執行整個方案的搜尋和替換:
grep -r "\.BarcodeValue" --include="*.cs" .
grep -r "\.BarcodeType" --include="*.cs" .
將 result.BarcodeValue 替換為 result.Value,將 result.BarcodeType 替換為 result.Format 在所有找到的檔案中。
問題 2:孤立的授權配置呼叫
BarcodeXpress: SetSolutionKey 和 SetOEMLicenseKey 呼叫 — 外加任何自定義的斷言檢測解碼輸出中的 "UNLICENSED accusoft.com" 水印 — 存在於許多程式碼庫中作為防禦水印輸出失敗模式的方法。
解決方案: 定位並刪除所有這樣的呼叫位置 ——IronBarcode沒有等效的狀態。 授權密鑰要麼有效要麼無效,如果無效,則試用限制統一適用而不是降低單個解碼值:
grep -r "SetOEMLicenseKey" --include="*.cs" .
grep -r "SetSolutionName" --include="*.cs" .
grep -r "SetSolutionKey" --include="*.cs" .
grep -r "UNLICENSED accusoft" --include="*.cs" .
所有這些呼叫位置都可以刪除。
問題 3:Docker 授權檔案裝載到環境變數
BarcodeXpress: Docker 部署通常使用 COPY 或卷裝載指令將 BarcodeXpress 授權配置檔案裝載到容器中的已知路徑。
解決方案: 移除配置檔案複製,並以環境變數替代:
# Remove this
COPY accusoft-license.lic /app/license/
# Add this
ENV IRONBARCODE_LICENSE=YOUR-LICENSE-KEY
在應用程式啟動時:
IronBarCode.License.LicenseKey =
Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE");Imports System
IronBarCode.License.LicenseKey = Environment.GetEnvironmentVariable("IRONBARCODE_LICENSE")在 Kubernetes 中,授權密鑰在 pod 規範中成為秘密引用:
env:
- name: IRONBARCODE_LICENSE
valueFrom:
secretKeyRef:
name: ironbarcode-secrets
key: license-key
問題 4:速率限制處理程式碼
BarcodeXpress: 處理在標準版 40-PPM 上限下的大批量文件的團隊通常會加入程式碼,以在多份文件群組間休眠,跟踪每分鐘計數,或者引入延遲以保持在限制內。
解決方案: 刪除所有速率限制程式碼。 用以下命令定位它:
grep -r "40\|PPM\|pagesPerMinute\|minuteStart" --include="*.cs" .
IronBarcode 沒有吞吐量上限——以您基礎結構支援的任何速度進行處理。
問題 5:執行緒安全——移除實例池
BarcodeXpress: 支援並行處理的程式碼庫通常維護一個 BarcodeXpress 實例池或使用 ThreadLocal<BarcodeXpress> 模式來隔離每個執行緒的有狀態閱讀器。
解決方案: 完全刪除池化邏輯。IronBarcode的 BarcodeReader.Read 和 BarcodeWriter.CreateBarcode 是無狀態靜態方法。 來自任何數量執行緒的並行呼叫不會相互干擾。
Accusoft BarcodeXpress遷移檢查清單
遷移前任務
審核程式碼庫以識別在進行任何程式碼更改之前所有 BarcodeXpress 用途:
grep -r "BarcodeXpress" --include="*.cs" .
grep -r "Accusoft" --include="*.cs" .
grep -r "SetSolutionName" --include="*.cs" .
grep -r "SetSolutionKey" --include="*.cs" .
grep -r "SetOEMLicenseKey" --include="*.cs" .
grep -r "reader\.Analyze" --include="*.cs" .
grep -r "writer\.CreateBitmap" --include="*.cs" .
grep -r "\.BarcodeValue" --include="*.cs" .
grep -r "\.BarcodeType" --include="*.cs" .
grep -r "BarcodeType\." --include="*.cs" .
- 記下哪些條碼格式在
BarcodeTypes指派中被明確列出——這些在IronBarcode中都變為自動檢測 - 確認可以刪除的任何速率限制處理程式碼
- 確認僅為支持 BarcodeXpress 閱讀而新增的任何 PDF 渲染庫——這些也可以刪除
- 獲取您的IronBarcode授權密鑰並將其新增到您的機密管理器中
程式碼更新任務
- 從所有
Accusoft.BarcodeXpress.NetCore檔案中刪除.csproj - 將
IronBarcode新增到需要條碼功能的所有.csproj檔案中 - 在所有檔案中,用
using Accusoft.BarcodeXpressSdk;替換using IronBarCode; - 新增
IronBarCode.License.LicenseKey = ...到應用程式啟動 - 刪除所有
BarcodeXpress建構函式呼叫和實例欄位 - 刪除所有
SetSolutionKey和SetOEMLicenseKey呼叫 - 刪除所有掃描解碼輸出中的 "UNLICENSED accusoft.com" 水印的自定義斷言
- 將
new Bitmap(path)+reader.Analyze(bitmap)替換為BarcodeReader.Read(path) - 刪除所有
reader.BarcodeTypes = ...指派 - 將
result.BarcodeValue替換為result.Value - 將
result.BarcodeType替換為result.Format - 將
writer.CreateBitmap()+bitmap.Save(path)替換為BarcodeWriter.CreateBarcode(data, encoding).SaveAsPng(path) - 刪除速率限制調節程式碼
- 移除中介 PDF 渲染程式碼(如果存在)
- 刪除 BarcodeXpress 實例的實例池或
ThreadLocal模式 - 從 Dockerfile 和 docker-compose 檔案中移除授權檔案裝載
- 新增
IRONBARCODE_LICENSE環境變數到 Docker 和容器配置中 - 更新 Kubernetes 機密和pod 規範
- 更新 CI/CD 管線機密——移除
ACCUSOFT_SOLUTION_KEY和ACCUSOFT_RUNTIME_KEY; 新增IRONBARCODE_LICENSE
遷移後測試
- 構建解決方案——修復重命名屬性後的任何剩餘編譯錯誤
- 對所有條碼讀取運算進行單元測試
- 對所有條碼生成運算進行單元測試
- 如果適用的話,用 PDF 輸入進行測試
- 運行批量處理測試,以確認無吞吐量限制行為
- 部署到預備環境,並確認授權密鑰能從環境變數中正確解析
遷移到IronBarcode的主要優勢
消除雙鑰授權複雜性: 套裝 SetSolutionKey 和 SetOEMLicenseKey 完全消失。 一個密鑰涵蓋從開發到生產的每個環境,並且試用模式返回完整的解碼值(而不是蓋上 "UNLICENSED accusoft.com" 標記),以便在真實文件上進行預購基準測試成為可能。
無運行時授權最低購買量: BarcodeXpress 要求任何生產部署至少需要五個運行時授權。IronBarcode沒有運行時授權概念——單一永久密鑰涵蓋其層級內的任何數量的生產部署。
無上限的吞吐量: 標準版 40-PPM 上限和任何為保持範圍內而編寫的速率限制程式碼可以被刪除。IronBarcode的處理速度按照底層硬體和網路支援的速度運行,在任何價格層級上都沒有由軟體強加的上限。
原生 PDF 閱讀: BarcodeReader.Read("document.pdf") 直接處理 PDF 文件,返回含有頁碼、格式、值和置信度分數的每頁結果。 僅為支持 BarcodeXpress 而新增的任何 PDF 渲染庫可以被刪除,從而減少相依性和授權成本。
無狀態執行緒安全: BarcodeReader.Read 和 BarcodeWriter.CreateBarcode 是無狀態靜態方法。 實例池、ThreadLocal 模式和每個執行緒初始化區塊都可以被移除。 使用 Parallel.ForEach 進行並行處理不需要除了移除執行緒解決方案外的任何結構更改。
簡化的容器部署: Docker 和 Kubernetes 部署使用單一環境變數進行授權配置。 授權文件分發、授權伺服器基礎架構和配置文件裝載全部被消除。

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。