使用IRONBARCODE C# USB條碼掃描器:構建完整的掃描應用程式 Jordi Bardia 更新:2026年2月27日 下載 IronBarcode NuGet 下載 DLL 下載 開始免費試用 LLM副本 LLM副本 將頁面複製為 Markdown 格式,用於 LLMs 在 ChatGPT 中打開 請向 ChatGPT 諮詢此頁面 在雙子座打開 請向 Gemini 詢問此頁面 在 Grok 中打開 向 Grok 詢問此頁面 打開困惑 向 Perplexity 詢問有關此頁面的信息 分享 在 Facebook 上分享 分享到 X(Twitter) 在 LinkedIn 上分享 複製連結 電子郵件文章 USB 條碼掃描器作為標準鍵盤輸入裝置連接到 C# 應用程序,將掃描的資料作為鍵入的字元發送,然後按 Enter 鍵。 這種 HID 鍵盤楔形行為使整合變得簡單——您的應用程式無需任何特殊驅動程式或 SDK 即可接收文字輸入。 IronBarcode處理原始輸入以驗證格式、提取結構化資料並產生回應條碼,將簡單的掃描事件轉換為庫存管理、零售銷售點和物流追蹤系統的完整資料管道。 零售、倉儲和製造營運都依賴準確、快速的條碼掃描。 當開發人員將 USB 掃描器連接到 Windows Forms 或 WPF 應用程式時,掃描器的行為與鍵盤完全相同——資料會顯示在文字方塊中,按下 Enter 鍵表示已接收到完整的條碼。 真正的挑戰不在於如何取得數據; 它正在正確處理。 IronBarcode 的條碼驗證功能可檢查格式完整性,提取批號或 GS1 應用識別碼等字段,並可立即產生新的條碼作為回應。 本指南將逐步引導您建立一個可用於生產環境的 C# USB 條碼掃描器應用程式。您將安裝庫、擷取掃描器輸入、驗證條碼格式、產生回應標籤,並組裝一個高吞吐量的基於佇列的處理器。 每個部分都包含完整的、可運行的程式碼,目標框架為.NET 10,並在適當情況下採用頂級語句樣式。 如何使用 C# 實作 USB 條碼掃描器? 為什麼 HID 鍵盤楔形模式能夠簡化整合? 大多數 USB 條碼掃描器出廠時預設為 HID 鍵盤楔形模式。 當您將 USB 裝置插入 Windows 電腦時,作業系統會將其註冊為 USB 儲存裝置(用於設定)和鍵盤(用於資料輸入)。 當掃描條碼時,裝置會將解碼後的條碼值轉換為按鍵,並將其發送到目前具有焦點的應用程式窗口,並在末尾添加回車符。 從 C# 開發人員的角度來看,這意味著您不需要供應商 SDK、COM 庫或特殊的 USB API。只需一個帶有 KeyDown 事件處理程序的標準 TextBox 即可捕獲輸入。 主要的整合挑戰在於區分掃描器輸入和真正的鍵盤輸入。 掃描器通常會在很短的時間內(通常不到 50 毫秒)完成所有字元的掃描,而人類打字則會將擊鍵過程分散到數百毫秒內。 控制連擊時間是過濾掉意外按鍵的可靠方法。 專業級掃描器還支援串列(RS-232 或虛擬 COM 連接埠)和直接 USB HID 模式,讓您可以更好地控制前綴/後綴字元和掃描觸發器。 下面這種介面模式可以處理這兩種情況: public interface IScannerInput { event EventHandler<string> BarcodeScanned; void StartListening(); void StopListening(); } public class KeyboardWedgeScanner : IScannerInput { public event EventHandler<string> BarcodeScanned; private readonly TextBox _inputBox; private readonly System.Windows.Forms.Timer _burstTimer; private readonly System.Text.StringBuilder _buffer = new(); public KeyboardWedgeScanner(TextBox inputBox) { _inputBox = inputBox; _burstTimer = new System.Windows.Forms.Timer { Interval = 80 }; _burstTimer.Tick += OnBurstTimeout; _inputBox.KeyPress += OnKeyPress; } private void OnKeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)Keys.Enter) { _burstTimer.Stop(); string value = _buffer.ToString().Trim(); _buffer.Clear(); if (value.Length > 0) BarcodeScanned?.Invoke(this, value); } else { _buffer.Append(e.KeyChar); _burstTimer.Stop(); _burstTimer.Start(); } e.Handled = true; } private void OnBurstTimeout(object sender, EventArgs e) { _burstTimer.Stop(); _buffer.Clear(); // incomplete burst -- discard } public void StartListening() => _inputBox.Focus(); public void StopListening() => _inputBox.Enabled = false; } public class SerialPortScanner : IScannerInput { public event EventHandler<string> BarcodeScanned; private readonly System.IO.Ports.SerialPort _port; public SerialPortScanner(string portName, int baudRate = 9600) { _port = new System.IO.Ports.SerialPort(portName, baudRate); _port.DataReceived += OnDataReceived; } private void OnDataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { string data = _port.ReadLine().Trim(); if (data.Length > 0) BarcodeScanned?.Invoke(this, data); } public void StartListening() => _port.Open(); public void StopListening() => _port.Close(); } public interface IScannerInput { event EventHandler<string> BarcodeScanned; void StartListening(); void StopListening(); } public class KeyboardWedgeScanner : IScannerInput { public event EventHandler<string> BarcodeScanned; private readonly TextBox _inputBox; private readonly System.Windows.Forms.Timer _burstTimer; private readonly System.Text.StringBuilder _buffer = new(); public KeyboardWedgeScanner(TextBox inputBox) { _inputBox = inputBox; _burstTimer = new System.Windows.Forms.Timer { Interval = 80 }; _burstTimer.Tick += OnBurstTimeout; _inputBox.KeyPress += OnKeyPress; } private void OnKeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)Keys.Enter) { _burstTimer.Stop(); string value = _buffer.ToString().Trim(); _buffer.Clear(); if (value.Length > 0) BarcodeScanned?.Invoke(this, value); } else { _buffer.Append(e.KeyChar); _burstTimer.Stop(); _burstTimer.Start(); } e.Handled = true; } private void OnBurstTimeout(object sender, EventArgs e) { _burstTimer.Stop(); _buffer.Clear(); // incomplete burst -- discard } public void StartListening() => _inputBox.Focus(); public void StopListening() => _inputBox.Enabled = false; } public class SerialPortScanner : IScannerInput { public event EventHandler<string> BarcodeScanned; private readonly System.IO.Ports.SerialPort _port; public SerialPortScanner(string portName, int baudRate = 9600) { _port = new System.IO.Ports.SerialPort(portName, baudRate); _port.DataReceived += OnDataReceived; } private void OnDataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { string data = _port.ReadLine().Trim(); if (data.Length > 0) BarcodeScanned?.Invoke(this, data); } public void StartListening() => _port.Open(); public void StopListening() => _port.Close(); } $vbLabelText $csharpLabel 鍵盤楔形實作中的突發計時器是關鍵細節。 每次按鍵都會重置,並且只有在字元停止輸入時才會觸發——這意味著打字速度較慢的真正鍵盤用戶,其未完成的輸入將被丟棄,而不是被當作條碼掃描處理。 如何處理多個掃描器品牌? 企業環境中經常在同一樓層混合運行 Honeywell、Zebra(以前稱為 Symbol/Motorola)和 Datalogic 掃描儀。 每個廠商都有自己的預設終止符、波特率和前綴/後綴約定。 配置模型使您的應用程式具有靈活性: public class ScannerConfiguration { public string ScannerType { get; set; } = "KeyboardWedge"; public string PortName { get; set; } = "COM3"; public int BaudRate { get; set; } = 9600; public string Terminator { get; set; } = "\r\n"; public bool EnableBeep { get; set; } = true; public Dictionary<string, string> BrandSettings { get; set; } = new(); public static ScannerConfiguration GetHoneywellConfig() => new() { ScannerType = "Serial", BaudRate = 115200, BrandSettings = new Dictionary<string, string> { { "Prefix", "STX" }, { "Suffix", "ETX" }, { "TriggerMode", "Manual" } } }; public static ScannerConfiguration GetZebraConfig() => new() { ScannerType = "KeyboardWedge", BrandSettings = new Dictionary<string, string> { { "ScanMode", "Continuous" }, { "BeepVolume", "High" } } }; } public class ScannerConfiguration { public string ScannerType { get; set; } = "KeyboardWedge"; public string PortName { get; set; } = "COM3"; public int BaudRate { get; set; } = 9600; public string Terminator { get; set; } = "\r\n"; public bool EnableBeep { get; set; } = true; public Dictionary<string, string> BrandSettings { get; set; } = new(); public static ScannerConfiguration GetHoneywellConfig() => new() { ScannerType = "Serial", BaudRate = 115200, BrandSettings = new Dictionary<string, string> { { "Prefix", "STX" }, { "Suffix", "ETX" }, { "TriggerMode", "Manual" } } }; public static ScannerConfiguration GetZebraConfig() => new() { ScannerType = "KeyboardWedge", BrandSettings = new Dictionary<string, string> { { "ScanMode", "Continuous" }, { "BeepVolume", "High" } } }; } $vbLabelText $csharpLabel 將這些配置儲存在設定檔或資料庫中,意味著倉庫工作人員可以更換掃描器型號而無需重新部署。 ScannerType 欄位決定在啟動時實例化哪個 IScannerInput 實作。 如何在 C# 專案中安裝IronBarcode ? 透過NuGet添加IronBarcode的最快方法是什麼? 在 Visual Studio 中開啟程式包管理器控制台並執行: Install-Package IronBarCode Install-Package IronBarCode SHELL 或者,使用.NET CLI: dotnet add package IronBarCode dotnet add package IronBarCode SHELL 這兩個指令都會從NuGet取得最新版本,並將程式集參考新增到您的專案檔案中。此函式庫面向.NET Standard 2.0,因此無需任何額外的相容性修補程式即可在.NET Framework 4.6.2 到.NET 10 上執行。 安裝完成後,請在呼叫任何IronBarcode方法之前設定您的許可證密鑰。 用於開發和評估的免費試用金鑰可從IronBarcode許可頁面取得: IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"; IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"; $vbLabelText $csharpLabel 對於容器化部署, IronBarcode可與 Linux 上的 Docker 搭配使用;對於雲端函數,它支援AWS Lambda和Azure Functions 。 如何使用IronBarcode來驗證掃描的條碼? 格式驗證的正確方法是什麼? IronBarcode支援 30 多種條碼符號體系,包括Code 128 、 EAN-13 、 Code 39 、 QR 碼和Data Matrix 。 對於 USB 掃描器應用,驗證模式會將掃描的字串重新編碼為條碼影像,並立即透過解碼器將其讀取回來。 這次往返驗證確認該字串是聲明格式的有效值: public class BarcodeValidator { public async Task<ValidationResult> ValidateAsync(string scannedText, BarcodeEncoding preferredFormat = BarcodeEncoding.Code128) { var result = new ValidationResult { RawInput = scannedText }; try { var barcode = BarcodeWriter.CreateBarcode(scannedText, preferredFormat); var readResults = await BarcodeReader.ReadAsync(barcode.ToBitmap()); if (readResults.Any()) { var first = readResults.First(); result.IsValid = true; result.Format = first.BarcodeType; result.Value = first.Value; result.Confidence = first.Confidence; } else { result.IsValid = false; result.Error = "No barcode could be decoded from the scanned input."; } } catch (Exception ex) { result.IsValid = false; result.Error = ex.Message; } return result; } } public record ValidationResult { public string RawInput { get; init; } = ""; public bool IsValid { get; set; } public BarcodeEncoding Format { get; set; } public string Value { get; set; } = ""; public float Confidence { get; set; } public string Error { get; set; } = ""; } public class BarcodeValidator { public async Task<ValidationResult> ValidateAsync(string scannedText, BarcodeEncoding preferredFormat = BarcodeEncoding.Code128) { var result = new ValidationResult { RawInput = scannedText }; try { var barcode = BarcodeWriter.CreateBarcode(scannedText, preferredFormat); var readResults = await BarcodeReader.ReadAsync(barcode.ToBitmap()); if (readResults.Any()) { var first = readResults.First(); result.IsValid = true; result.Format = first.BarcodeType; result.Value = first.Value; result.Confidence = first.Confidence; } else { result.IsValid = false; result.Error = "No barcode could be decoded from the scanned input."; } } catch (Exception ex) { result.IsValid = false; result.Error = ex.Message; } return result; } } public record ValidationResult { public string RawInput { get; init; } = ""; public bool IsValid { get; set; } public BarcodeEncoding Format { get; set; } public string Value { get; set; } = ""; public float Confidence { get; set; } public string Error { get; set; } = ""; } $vbLabelText $csharpLabel 對於供應鏈應用中使用的GS1-128 條碼,掃描的字串包含括號中的應用標識符前綴,例如 GTIN 的 (01) 和到期日期的 (17)。 當您指定 BarcodeEncoding.GS1_128 時, IronBarcode會自動解析這些應用程式識別碼。 開發人員應該實現哪種EAN-13校驗和邏輯? 零售POS應用通常需要在將EAN-13值傳遞給定價查詢之前,獨立驗證EAN-13校驗位。 EAN-13的Luhn式校驗和在前12位數字中交替使用權重1和3: public static bool ValidateEan13Checksum(string value) { if (value.Length != 13 || !value.All(char.IsDigit)) return false; int sum = 0; for (int i = 0; i < 12; i++) { int digit = value[i] - '0'; sum += (i % 2 == 0) ? digit : digit * 3; } int expectedCheck = (10 - (sum % 10)) % 10; return expectedCheck == (value[12] - '0'); } public static bool ValidateEan13Checksum(string value) { if (value.Length != 13 || !value.All(char.IsDigit)) return false; int sum = 0; for (int i = 0; i < 12; i++) { int digit = value[i] - '0'; sum += (i % 2 == 0) ? digit : digit * 3; } int expectedCheck = (10 - (sum % 10)) % 10; return expectedCheck == (value[12] - '0'); } $vbLabelText $csharpLabel 這種純邏輯檢查在編碼之前運行,以避免在高容量零售環境中每次掃描時產生往返影像產生的開銷。 根據GS1 規範,當去掉前導零時,UPC-A(12 位數)的校驗位演算法是相同的。 如何根據掃描的輸入產生響應條碼? 應用程式何時應該在掃描後建立新條碼? 倉庫收貨中常見的模式是"掃描和重新貼標籤"工作流程:入庫物品帶有供應商條碼(通常是 EAN-13 或 ITF-14),倉庫管理系統需要列印一個帶有其自身位置和批號的內部 Code 128 標籤。 IronBarcode 的產生功能只需幾行程式碼即可完成: public class InventoryLabelGenerator { private readonly string _outputDirectory; public InventoryLabelGenerator(string outputDirectory) { _outputDirectory = outputDirectory; Directory.CreateDirectory(_outputDirectory); } public async Task<string> GenerateLabelAsync(string internalCode, string locationCode) { string fullCode = $"{internalCode}|{locationCode}|{DateTime.UtcNow:yyyyMMdd}"; // Primary Code 128 label for scanners var linearBarcode = BarcodeWriter.CreateBarcode(fullCode, BarcodeEncoding.Code128); linearBarcode.ResizeTo(500, 140); linearBarcode.SetMargins(12); linearBarcode.AddAnnotationTextAboveBarcode(fullCode); linearBarcode.ChangeBarCodeColor(IronSoftware.Drawing.Color.Black); // QR code companion for mobile apps var qrCode = BarcodeWriter.CreateQrCode(fullCode); qrCode.ResizeTo(200, 200); qrCode.SetMargins(8); string timestamp = DateTime.UtcNow.ToString("yyyyMMddHHmmss"); string pngPath = Path.Combine(_outputDirectory, $"{internalCode}_{timestamp}.png"); string pdfPath = Path.Combine(_outputDirectory, $"{internalCode}_{timestamp}.pdf"); await Task.Run(() => { linearBarcode.SaveAsPng(pngPath); linearBarcode.SaveAsPdf(pdfPath); }); return pngPath; } } public class InventoryLabelGenerator { private readonly string _outputDirectory; public InventoryLabelGenerator(string outputDirectory) { _outputDirectory = outputDirectory; Directory.CreateDirectory(_outputDirectory); } public async Task<string> GenerateLabelAsync(string internalCode, string locationCode) { string fullCode = $"{internalCode}|{locationCode}|{DateTime.UtcNow:yyyyMMdd}"; // Primary Code 128 label for scanners var linearBarcode = BarcodeWriter.CreateBarcode(fullCode, BarcodeEncoding.Code128); linearBarcode.ResizeTo(500, 140); linearBarcode.SetMargins(12); linearBarcode.AddAnnotationTextAboveBarcode(fullCode); linearBarcode.ChangeBarCodeColor(IronSoftware.Drawing.Color.Black); // QR code companion for mobile apps var qrCode = BarcodeWriter.CreateQrCode(fullCode); qrCode.ResizeTo(200, 200); qrCode.SetMargins(8); string timestamp = DateTime.UtcNow.ToString("yyyyMMddHHmmss"); string pngPath = Path.Combine(_outputDirectory, $"{internalCode}_{timestamp}.png"); string pdfPath = Path.Combine(_outputDirectory, $"{internalCode}_{timestamp}.pdf"); await Task.Run(() => { linearBarcode.SaveAsPng(pngPath); linearBarcode.SaveAsPdf(pdfPath); }); return pngPath; } } $vbLabelText $csharpLabel 將文件儲存為 PDF 格式對於可以透過網路共用接收 PDF 輸入的標籤印表機尤其有用。 您也可以匯出為 SVG 格式以獲得向量品質的熱敏標籤輸出,或匯出為位元組流以直接傳送到標籤印表機 API。 IronBarcode支援廣泛的樣式自訂,包括自訂顏色、邊距調整、人可讀文字疊加,以及為二維碼嵌入徽標,以製作品牌標記的移動標籤。 ![Windows Forms 應用程式介面,示範 IronBarcode 的雙條碼產生功能。 介面顯示已成功產生庫存編號為"INV-20250917-helloworld"的 Code 128 線性條碼和二維碼。 頂部的輸入欄位允許使用者輸入自訂庫存代碼,並有一個"產生"按鈕來建立條碼。 成功訊息"專案處理成功 - 已產生標籤"確認操作已完成。 Code 128 條碼被標記為主要的庫存追蹤格式,而下方的二維碼則被標記為行動友善替代方案。該應用程式採用專業的灰色背景和清晰的視覺層次結構,展示了IronBarcode如何幫助開發人員創建多格式條碼生成系統,以實現完整的庫存管理。 如何建立一個完整的高容量掃描應用程式? 基於生產隊列的實作方式是怎樣的? 對於每分鐘處理數十次掃描的應用程式來說,UI 執行緒上的簡單同步處理程序會成為瓶頸。 以下模式使用 ConcurrentQueue<t> 和後台處理循環將掃描擷取與處理解耦。 IronBarcode的非同步 API處理驗證,而不會阻塞使用者介面: using IronBarCode; using System.Collections.Concurrent; public partial class HighVolumeScanner : Form { private readonly ConcurrentQueue<(string Data, DateTime Timestamp)> _scanQueue = new(); private readonly SemaphoreSlim _semaphore; private readonly CancellationTokenSource _cts = new(); private IScannerInput _scanner; public HighVolumeScanner() { InitializeComponent(); IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"; _semaphore = new SemaphoreSlim(Environment.ProcessorCount); InitializeScanner(); _ = RunProcessingLoopAsync(); } private void InitializeScanner() { _scanner = System.IO.Ports.SerialPort.GetPortNames().Any() ? new SerialPortScanner("COM3", 115200) : new KeyboardWedgeScanner(txtScannerInput); _scanner.BarcodeScanned += (_, barcode) => _scanQueue.Enqueue((barcode, DateTime.UtcNow)); _scanner.StartListening(); } private async Task RunProcessingLoopAsync() { while (!_cts.Token.IsCancellationRequested) { if (_scanQueue.TryDequeue(out var scan)) { await _semaphore.WaitAsync(_cts.Token); _ = Task.Run(async () => { try { await ProcessScanAsync(scan.Data, scan.Timestamp); } finally { _semaphore.Release(); } }, _cts.Token); } else { await Task.Delay(10, _cts.Token); } } } private async Task ProcessScanAsync(string rawData, DateTime scanTime) { var options = new BarcodeReaderOptions { Speed = ReadingSpeed.均衡, ExpectMultipleBarcodes = false, ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, MaxParallelThreads = 1 }; var testBarcode = BarcodeWriter.CreateBarcode(rawData, BarcodeEncoding.Code128); var results = await BarcodeReader.ReadAsync(testBarcode.ToBitmap(), options); if (results.Any()) { var item = results.First(); BeginInvoke(() => UpdateInventoryDisplay(item.Value, scanTime)); } else { BeginInvoke(() => LogRejectedScan(rawData, scanTime)); } } protected override void OnFormClosing(FormClosingEventArgs e) { _cts.Cancel(); _scanner.StopListening(); base.OnFormClosing(e); } } using IronBarCode; using System.Collections.Concurrent; public partial class HighVolumeScanner : Form { private readonly ConcurrentQueue<(string Data, DateTime Timestamp)> _scanQueue = new(); private readonly SemaphoreSlim _semaphore; private readonly CancellationTokenSource _cts = new(); private IScannerInput _scanner; public HighVolumeScanner() { InitializeComponent(); IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"; _semaphore = new SemaphoreSlim(Environment.ProcessorCount); InitializeScanner(); _ = RunProcessingLoopAsync(); } private void InitializeScanner() { _scanner = System.IO.Ports.SerialPort.GetPortNames().Any() ? new SerialPortScanner("COM3", 115200) : new KeyboardWedgeScanner(txtScannerInput); _scanner.BarcodeScanned += (_, barcode) => _scanQueue.Enqueue((barcode, DateTime.UtcNow)); _scanner.StartListening(); } private async Task RunProcessingLoopAsync() { while (!_cts.Token.IsCancellationRequested) { if (_scanQueue.TryDequeue(out var scan)) { await _semaphore.WaitAsync(_cts.Token); _ = Task.Run(async () => { try { await ProcessScanAsync(scan.Data, scan.Timestamp); } finally { _semaphore.Release(); } }, _cts.Token); } else { await Task.Delay(10, _cts.Token); } } } private async Task ProcessScanAsync(string rawData, DateTime scanTime) { var options = new BarcodeReaderOptions { Speed = ReadingSpeed.均衡, ExpectMultipleBarcodes = false, ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, MaxParallelThreads = 1 }; var testBarcode = BarcodeWriter.CreateBarcode(rawData, BarcodeEncoding.Code128); var results = await BarcodeReader.ReadAsync(testBarcode.ToBitmap(), options); if (results.Any()) { var item = results.First(); BeginInvoke(() => UpdateInventoryDisplay(item.Value, scanTime)); } else { BeginInvoke(() => LogRejectedScan(rawData, scanTime)); } } protected override void OnFormClosing(FormClosingEventArgs e) { _cts.Cancel(); _scanner.StopListening(); base.OnFormClosing(e); } } $vbLabelText $csharpLabel SemaphoreSlim 將並發驗證任務限制為邏輯處理器的數量,防止在突發掃描事件期間建立失控的執行緒。 BeginInvoke 呼叫安全地將 UI 更新序列化回主執行緒。 如何針對不同的掃描範圍調整效能? BarcodeReaderOptions.Speed 屬性接受 ReadingSpeed.均衡 和 ReadingSpeed.詳細的。 對於已知字串值的 USB 掃描器輸入,均衡 是適當的-解碼器只需要確認格式,不需要在影像中尋找條碼。 根據IronBarcode 的讀取速度文檔,快點 模式會跳過一些失真校正演算法,這對於乾淨的掃描器輸出來說是安全的,但在基於影像的場景中可能會漏掉損壞的條碼。 下表總結了每種速度模式的使用時機: IronBarcode讀取速度模式及其適用場景 速度模式 最適合 權衡 快點 清潔的USB掃描器輸入,高吞吐量 可能漏檢嚴重損壞或傾斜的條碼 均衡 混合輸入-USB掃描器加影像導入 CPU佔用率適中,準確率高 詳細的 標籤破損、列印對比度低、PDF導入 CPU 使用率高,吞吐量最慢 對於除了 USB 掃描器輸入外,還處理影像或 PDF 的應用程序,IronBarcode 可以使用相同的 API 介面從 PDF 文件和多頁 TIFF 檔案IronBarcode讀取條碼。 ![專業 Windows Forms 條碼掃描器應用程序,展示了 IronBarcode 的即時庫存追蹤功能。 介面採用簡潔的雙面板設計,搭配精緻的深藍色標題列。 左側面板顯示掃描歷史記錄列表,其中顯示了四個成功掃描的庫存項目(INV-001 至 INV-004),並帶有精確的時間戳和掃描狀態指示器。 每個項目都包含詳細的元數據,例如條碼類型和置信度。 右側面板顯示動態產生的摘要條碼,其中顯示"商品數量:4",並具有專業的樣式和適當的邊距。 底部的操作按鈕包括"清除清單"、"匯出資料"和"列印標籤",用於完整的庫存管理。 狀態列顯示"掃描器:已連線" | 模式:連續 | 上次掃描時間:2 秒前,這展示了IronBarcode為生產庫存系統提供的即時監控功能和專業的企業級設計。 如何處理掃描器應用程式中的極端情況和錯誤? 開發人員應該預見哪些故障模式? USB掃描器應用程式的故障方式是可以預見的。 最常見的問題及其緩解措施如下: 掃描器斷開連接-當 USB 掃描器拔出時,鍵盤楔形文字方塊將失去其虛擬鍵盤。 最簡單的緩解措施是使用週期性定時器來檢查 _inputBox.Focused,如果掃描器仍然列在已連接的 HID 設備中,則重新聚焦它。 對於串行掃描儀,SerialPort.GetPortNames() 檢測重新連接。 條碼格式不明確-有些產品帶有條碼,這些條碼在多種條碼格式中均有效。 例如,一個 12 位元數字字串既是有效的 UPC-A,也是有效的 Code 128。在 BarcodeReaderOptions 中指定 ExpectBarcodeTypes 可以將解碼器限制為預期格式,並消除歧義。 IronBarcode故障排除指南涵蓋了特定格式的識別技巧。 無效格式異常-- 如果 BarcodeWriter.CreateBarcode 接收到違反所選編碼規則的字串(例如,在僅包含數字的 EAN-13 欄位中包含字母字元),則會拋出 IronBarCode.Exceptions.InvalidBarcodeException 例外。 將呼叫包裝在 try-catch 語句中,並回退到僅字串驗證路徑,可以保持應用程式運行。 按鍵時間衝突-在操作員也手動向同一個文字方塊輸入內容的環境中,前面所描述的突發計時器方法是主要的防禦措施。 二級保護是最小長度:大多數真正的條碼至少有 8 個字符,因此短於此長度的字串可以視為鍵盤輸入。 在排查串行掃描器連接問題時,Microsoft .NET文件中關於System.IO.Ports.SerialPort 的內容非常有用,特別是關於 ReadTimeout 和 WriteTimeout 設定的問題。 為了符合零售業的監管規定, GS1 通用規範為每個應用識別碼定義了有效值範圍。 如何將應用程式擴展到行動和網路平台? 上圖所示的掃描器介面模式 -- IScannerInput 與 BarcodeScanned 事件 -- 將硬體與處理邏輯隔離。 交換實作方式可以讓相同的驗證和產生程式碼在不同的平台上運作: .NET MAUI為用作行動接收站的 Android 和 iOS 平板電腦提供基於相機的掃描器實作。 Blazor伺服器支援基於瀏覽器的掃描,透過JavaScript存取相機,並將資料輸入到同一個 BarcodeScanned 事件中。 Android和iOS原生實作為行動開發者提供了相機掃描功能,後端使用相同的IronBarcode解碼器。 對於雲端原生架構,驗證和標籤產生步驟可以作為Azure Functions運行,由佇列訊息觸發,而桌面應用程式僅充當掃描器輸入網關。 當需要集中管理標籤列印邏輯以進行合規性審核時,這種分離方式尤其有用。 下一步計劃是什麼? 使用IronBarcode建立 USB 條碼掃描器應用程式涉及四個特定階段:透過突發時序偵測擷取鍵盤楔形輸入、透過 IronBarcode 的解碼器驗證掃描值、產生所需格式的回應標籤以及使用並發佇列處理大量掃描。 每個階段都是獨立的,可以單獨進行測試。 在此基礎上,可以考慮擴展應用程序,例如為批量處理場景添加多條碼讀取功能、為基於圖像的輸入添加作物區域優化功能,或者為較舊的倉庫設備添加MSI 條碼支援功能。 IronBarcode文件涵蓋了所有支援的格式和進階讀取器配置選項。 立即開始免費試用,取得開發許可證金鑰,並開始將IronBarcode整合到您的掃描應用程式中。 常見問題解答 什麼是 IronBarcode,它與 USB 條碼掃描器有何關係? IronBarcode 是一個函式庫,使開發人員能夠構建用於 USB 條碼掃描的強大 C# 應用程式。它提供了條碼驗證、數據提取和條碼生成等功能。 IronBarcode 可以驗證來自 USB 掃描器的條碼數據嗎? 是的,IronBarcode 可以驗證從 USB 掃描器截取的條碼數據,確保 C# 應用程式中的數據完整性和準確性。 IronBarcode 如何處理條碼生成? IronBarcode 可以即時生成新的條碼,使開發人員能夠在其 C# 應用程式中輕松創建和打印條碼。 IronBarcode 是否支持 USB 條碼掃描的錯誤處理? 是的,IronBarcode 包含全面的錯誤處理,以管理 USB 條碼掃描和處理過程中可能出現的常見問題。 IronBarcode 可以掃描哪些類型的條碼? IronBarcode 支持掃描各種條碼符號,包括 QR 碼、UPC、Code 39 等,這使其在各種應用中具有多功能性。 IronBarcode 能夠提取掃描條碼中的結構化信息嗎? 是的,IronBarcode 可以從掃描的條碼中提取結構化信息,協助高效數據處理和管理。 我如何開始在 C# 中構建 USB 條碼掃描器應用程式? 要開始在 C# 中構建 USB 條碼掃描器應用程序,您可以利用 IronBarcode,並結合提供的代碼示例和文檔來指導您的開發過程。 Jordi Bardia 立即與工程團隊聊天 軟體工程師 Jordi 在 Python、C# 和 C++ 上最得心應手,當他不在 Iron Software 展現技術時,便在做遊戲編程。在分担產品测测试,產品開發和研究的责任時,Jordi 為持续的產品改進增值。他说这种多样化的经验使他受到挑战并保持参与, 而这也是他与 Iron Software 中工作一大乐趣。Jordi 在佛罗里达州迈阿密长大,曾在佛罗里达大学学习计算机科学和统计学。 相關文章 發表日期 2026年3月8日 創建.NET應用程式的條碼專業SDK 全面的.NET條碼SDK,用於QR Codes、GS1、Data Matrix等。支持.NET 6-10、Core和Framework。 閱讀更多 發表日期 2026年3月8日 構建Barcode SDK C#:通過一個程式庫生成、讀取和掃描條碼 在C#中使用IronBarcode構建條碼SDK功能。生成條碼圖像,從文件掃描多個條碼,並使用一個.NET程式庫讀取QR Code。包含範例代碼。 閱讀更多 更新2026年3月1日 VB .NET條碼字體:如何在沒有字體依賴的情況下生成和列印條碼 在VB.NET中以現代方式處理條碼字體。使用IronBarcode生成Code 39和Code 128條碼圖像-無字體依賴。提供免費試用。 閱讀更多 ASP.NET條碼掃描器:文件上傳和REST API與IronBarcodeXamarin條碼生成器:使用Iron...
發表日期 2026年3月8日 創建.NET應用程式的條碼專業SDK 全面的.NET條碼SDK,用於QR Codes、GS1、Data Matrix等。支持.NET 6-10、Core和Framework。 閱讀更多
發表日期 2026年3月8日 構建Barcode SDK C#:通過一個程式庫生成、讀取和掃描條碼 在C#中使用IronBarcode構建條碼SDK功能。生成條碼圖像,從文件掃描多個條碼,並使用一個.NET程式庫讀取QR Code。包含範例代碼。 閱讀更多
更新2026年3月1日 VB .NET條碼字體:如何在沒有字體依賴的情況下生成和列印條碼 在VB.NET中以現代方式處理條碼字體。使用IronBarcode生成Code 39和Code 128條碼圖像-無字體依賴。提供免費試用。 閱讀更多