跳至頁尾內容
使用 IRONBARCODE

C# USB 條碼掃描器:IronBarcode 整合完整指南

USB條碼掃描器可作為鍵盤輸入設備,自動將掃描資料傳送至C#應用程式。 IronBarcode處理此輸入以驗證格式、提取結構化資料並產生新的條碼,從而為庫存管理系統建立完整的掃描解決方案,且部署複雜性極低。

零售、倉儲和庫存管理作業都依賴高效的條碼掃描。 借助IronBarcode及其有效的驗證和生成功能,開發人員可以建立可靠的 USB 條碼掃描器應用程序,這些應用程式的功能不僅限於簡單的資料收集。 該庫可以驗證條碼數據提取結構化訊息,並即時產生新的條碼

本指南示範如何在 C# 中將 USB 條碼掃描器與IronBarcode整合。 最終成果是可與.NET Framework 和 .NET 應用程式配合使用的即時掃描解決方案,可協助團隊有效率地管理庫存和追蹤物品。 無論是建立銷售點系統還是企業庫存管理解決方案,IronBarcode 的跨平台相容性都能確保應用程式在WindowsLinuxmacOS上流暢運作。

USB條碼掃描器如何與IronBarcode搭配使用?

為什麼鍵盤楔形模式對整合很重要?

大多數 USB 條碼掃描器以 HID 鍵盤楔形模式運行,模擬鍵盤輸入,從而輕鬆掃描條碼。 掃描條碼時,掃描器會"輸入"數據,然後按 Enter 鍵。 IronBarcode 透過驗證格式、提取結構化資料以及回應掃描立即產生條碼來改善這種原始輸入

了解不同的掃描器通訊模式有助於企業應用。 專業掃描器除了鍵盤楔形模式外,還支援串行通訊和直接 USB HID 模式:

// Example: Handling different scanner input modes
public interface IScannerInput
{
    event EventHandler<string> BarcodeScanned;
    void StartListening();
    void StopListening();
}

// Keyboard wedge implementation
public class KeyboardWedgeScanner : IScannerInput
{
    public event EventHandler<string> BarcodeScanned;
    private readonly TextBox _inputBox;

    public KeyboardWedgeScanner(TextBox inputBox)
    {
        _inputBox = inputBox;
        _inputBox.KeyPress += OnKeyPress;
    }

    private void OnKeyPress(object sender, KeyPressEventArgs e)
    {
        if (e.KeyChar == (char)Keys.Enter)
        {
            BarcodeScanned?.Invoke(this, _inputBox.Text);
            _inputBox.Clear();
        }
    }

    public void StartListening() => _inputBox.Focus();
    public void StopListening() => _inputBox.Enabled = false;
}

// Serial port implementation for professional scanners
public class SerialPortScanner : IScannerInput
{
    public event EventHandler<string> BarcodeScanned;
    private 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();
        BarcodeScanned?.Invoke(this, data);
    }

    public void StartListening() => _port.Open();
    public void StopListening() => _port.Close();
}
// Example: Handling different scanner input modes
public interface IScannerInput
{
    event EventHandler<string> BarcodeScanned;
    void StartListening();
    void StopListening();
}

// Keyboard wedge implementation
public class KeyboardWedgeScanner : IScannerInput
{
    public event EventHandler<string> BarcodeScanned;
    private readonly TextBox _inputBox;

    public KeyboardWedgeScanner(TextBox inputBox)
    {
        _inputBox = inputBox;
        _inputBox.KeyPress += OnKeyPress;
    }

    private void OnKeyPress(object sender, KeyPressEventArgs e)
    {
        if (e.KeyChar == (char)Keys.Enter)
        {
            BarcodeScanned?.Invoke(this, _inputBox.Text);
            _inputBox.Clear();
        }
    }

    public void StartListening() => _inputBox.Focus();
    public void StopListening() => _inputBox.Enabled = false;
}

// Serial port implementation for professional scanners
public class SerialPortScanner : IScannerInput
{
    public event EventHandler<string> BarcodeScanned;
    private 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();
        BarcodeScanned?.Invoke(this, data);
    }

    public void StartListening() => _port.Open();
    public void StopListening() => _port.Close();
}
$vbLabelText   $csharpLabel

開發人員如何擷取和驗證掃描器輸入?

// Capture scanner input and validate with IronBarcode
private async void ProcessScannerInput(string scannedData)
{
    try
    {
        // Validate the scanned data format
        var validationBarcode = BarcodeWriter.CreateBarcode(scannedData, BarcodeEncoding.Code128);
        var results = await BarcodeReader.ReadAsync(validationBarcode.ToBitmap());

        if (results.Any())
        {
            var result = results.First();

            // Extract metadata for enterprise systems
            var scanMetadata = new ScanMetadata
            {
                BarcodeType = result.BarcodeType,
                Value = result.Value,
                Confidence = result.Confidence,
                ScanTimestamp = DateTime.UtcNow,
                ScannerDevice = GetCurrentScannerInfo()
            };

            await ProcessValidBarcode(scanMetadata);
        }
        else
        {
            HandleInvalidScan(scannedData);
        }
    }
    catch (Exception ex)
    {
        LogScanError(ex, scannedData);
    }
}
// Capture scanner input and validate with IronBarcode
private async void ProcessScannerInput(string scannedData)
{
    try
    {
        // Validate the scanned data format
        var validationBarcode = BarcodeWriter.CreateBarcode(scannedData, BarcodeEncoding.Code128);
        var results = await BarcodeReader.ReadAsync(validationBarcode.ToBitmap());

        if (results.Any())
        {
            var result = results.First();

            // Extract metadata for enterprise systems
            var scanMetadata = new ScanMetadata
            {
                BarcodeType = result.BarcodeType,
                Value = result.Value,
                Confidence = result.Confidence,
                ScanTimestamp = DateTime.UtcNow,
                ScannerDevice = GetCurrentScannerInfo()
            };

            await ProcessValidBarcode(scanMetadata);
        }
        else
        {
            HandleInvalidScan(scannedData);
        }
    }
    catch (Exception ex)
    {
        LogScanError(ex, scannedData);
    }
}
$vbLabelText   $csharpLabel

這段程式碼透過各種方法捕捉掃描器輸入,並利用IronBarcode 的非同步讀取功能來驗證掃描的數據,而不會阻塞 UI 線程。 置信度閾值功能確保在生產環境中只處理高品質的掃描結果。

如何設定條碼掃描器項目?

有哪些必要的依賴項和配置?

首先,對於桌面場景,可以在 Visual Studio 中建立 Windows Forms 應用程式;對於基於 Web 的掃描應用程序,可以考慮使用Blazor 。 對於行動庫存解決方案, .NET MAUI提供出色的跨平台支持,具備AndroidiOS 功能。 然後透過 NuGet 套件管理器控制台安裝 IronBarcode

Install-Package BarCode

對於容器化部署, IronBarcode 可與 Docker 無縫協作,為企業環境提供部署清單。

快速入門:在 C# 中建立二維碼圖像

建立二維碼會產生一個可視化的影像,將資料編碼成可掃描的方塊:

Nuget Icon立即開始使用 NuGet 建立 PDF 檔案:

  1. 使用 NuGet 套件管理器安裝 IronBarcode

    PM > Install-Package BarCode

  2. 複製並運行這段程式碼。

    using IronBarCode;
    
    // Generate QR code from scanned inventory data
    string inventoryCode = "INV-2025-001";
    var qrCode = BarcodeWriter.CreateQrCode(inventoryCode);
    
    // Apply styling for professional labels
    qrCode.ResizeTo(300, 300);
    qrCode.SetMargins(10);
    qrCode.ChangeQrCodeColor(IronSoftware.Drawing.Color.DarkBlue);
    
    // Add logo for branding
    qrCode.AddLogoToQrCode("company_logo.png", 60, 60);
    
    // Save as high-quality image
    qrCode.SaveAsPng("inventory_qr.png");
    
    // Alternative: Save as PDF for printing
    qrCode.SaveAsPdf("inventory_qr.pdf");
  3. 部署到您的生產環境進行測試

    立即開始在您的專案中使用 IronBarcode,免費試用!
    arrow pointer

應用程式應該包含哪些命名空間?

請將以下必要的命名空間新增至表單中,並參考文件中的範例:

using IronBarCode;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.IO.Ports; // For serial scanners
using System.Diagnostics; // For performance monitoring
using IronBarCode;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.IO.Ports; // For serial scanners
using System.Diagnostics; // For performance monitoring
$vbLabelText   $csharpLabel

開發人員應該如何配置掃描器輸入表單?

企業應用受益於支援多種掃描器品牌的靈活掃描器配置系統:

public class ScannerConfiguration
{
    public string ScannerType { get; set; } // "KeyboardWedge", "Serial", "USB-HID"
    public string PortName { get; set; } // For serial scanners
    public int BaudRate { get; set; } = 9600;
    public string Terminator { get; set; } = "\r\n";
    public bool EnableBeep { get; set; } = true;

    // Brand-specific settings
    public Dictionary<string, string> BrandSettings { get; set; } = new();

    // Common scanner brand configurations
    public static ScannerConfiguration GetHoneywellConfig()
    {
        return new ScannerConfiguration
        {
            ScannerType = "Serial",
            BaudRate = 115200,
            BrandSettings = new Dictionary<string, string>
            {
                {"Prefix", "STX"},
                {"Suffix", "ETX"},
                {"TriggerMode", "Manual"}
            }
        };
    }

    public static ScannerConfiguration GetSymbolConfig()
    {
        return new ScannerConfiguration
        {
            ScannerType = "KeyboardWedge",
            BrandSettings = new Dictionary<string, string>
            {
                {"ScanMode", "Continuous"},
                {"BeepVolume", "High"}
            }
        };
    }
}
public class ScannerConfiguration
{
    public string ScannerType { get; set; } // "KeyboardWedge", "Serial", "USB-HID"
    public string PortName { get; set; } // For serial scanners
    public int BaudRate { get; set; } = 9600;
    public string Terminator { get; set; } = "\r\n";
    public bool EnableBeep { get; set; } = true;

    // Brand-specific settings
    public Dictionary<string, string> BrandSettings { get; set; } = new();

    // Common scanner brand configurations
    public static ScannerConfiguration GetHoneywellConfig()
    {
        return new ScannerConfiguration
        {
            ScannerType = "Serial",
            BaudRate = 115200,
            BrandSettings = new Dictionary<string, string>
            {
                {"Prefix", "STX"},
                {"Suffix", "ETX"},
                {"TriggerMode", "Manual"}
            }
        };
    }

    public static ScannerConfiguration GetSymbolConfig()
    {
        return new ScannerConfiguration
        {
            ScannerType = "KeyboardWedge",
            BrandSettings = new Dictionary<string, string>
            {
                {"ScanMode", "Continuous"},
                {"BeepVolume", "High"}
            }
        };
    }
}
$vbLabelText   $csharpLabel

如何使用 IronBarcode 驗證掃描的條碼?

條碼驗證的最佳方法是什麼?

IronBarcode 擅長驗證和解析多種格式的條碼資料。 此函式庫支援Code 128EAN-13Code 39一維條碼,以及QR 碼Data Matrix二維格式。 以下是一種改進的驗證方法:

public class BarcodeValidator
{
    private readonly Dictionary<BarcodeType, Func<string, bool>> _validators;

    public BarcodeValidator()
    {
        _validators = new Dictionary<BarcodeType, Func<string, bool>>
        {
            { BarcodeType.Code128, ValidateCode128 },
            { BarcodeType.EAN13, ValidateEAN13 },
            { BarcodeType.UPCA, ValidateUPCA },
            { BarcodeType.QRCode, ValidateQRCode }
        };
    }

    public async Task<ValidationResult> ValidateScannedBarcodeAsync(string scannedText)
    {
        var result = new ValidationResult();

        try
        {
            // Attempt multiple barcode formats for flexibility
            var encodings = new[] { 
                BarcodeEncoding.Code128, 
                BarcodeEncoding.EAN13,
                BarcodeEncoding.UPCA,
                BarcodeEncoding.QRCode 
            };

            foreach (var encoding in encodings)
            {
                try
                {
                    var barcode = BarcodeWriter.CreateBarcode(scannedText, encoding);
                    var validationResults = await BarcodeReader.ReadAsync(barcode.ToBitmap());

                    if (validationResults.Any())
                    {
                        var validated = validationResults.First();
                        result.IsValid = true;
                        result.Format = validated.BarcodeType;
                        result.Value = validated.Value;
                        result.Confidence = validated.Confidence;

                        // Apply format-specific validation
                        if (_validators.ContainsKey(validated.BarcodeType))
                        {
                            result.PassesBusinessRules = _validators___PROTECTED_LINK_35___;
                        }

                        break;
                    }
                }
                catch { /* Try next format */ }
            }

            // Handle GS1-128 for supply chain applications
            if (!result.IsValid && IsGS1Format(scannedText))
            {
                result = await ValidateGS1BarcodeAsync(scannedText);
            }
        }
        catch (Exception ex)
        {
            result.Error = ex.Message;
        }

        return result;
    }

    private bool ValidateEAN13(string value)
    {
        // EAN-13 checksum validation
        if (value.Length != 13) return false;

        int sum = 0;
        for (int i = 0; i < 12; i++)
        {
            int digit = int.Parse(value[i].ToString());
            sum += (i % 2 == 0) ? digit : digit * 3;
        }

        int checkDigit = (10 - (sum % 10)) % 10;
        return checkDigit == int.Parse(value[12].ToString());
    }
}
public class BarcodeValidator
{
    private readonly Dictionary<BarcodeType, Func<string, bool>> _validators;

    public BarcodeValidator()
    {
        _validators = new Dictionary<BarcodeType, Func<string, bool>>
        {
            { BarcodeType.Code128, ValidateCode128 },
            { BarcodeType.EAN13, ValidateEAN13 },
            { BarcodeType.UPCA, ValidateUPCA },
            { BarcodeType.QRCode, ValidateQRCode }
        };
    }

    public async Task<ValidationResult> ValidateScannedBarcodeAsync(string scannedText)
    {
        var result = new ValidationResult();

        try
        {
            // Attempt multiple barcode formats for flexibility
            var encodings = new[] { 
                BarcodeEncoding.Code128, 
                BarcodeEncoding.EAN13,
                BarcodeEncoding.UPCA,
                BarcodeEncoding.QRCode 
            };

            foreach (var encoding in encodings)
            {
                try
                {
                    var barcode = BarcodeWriter.CreateBarcode(scannedText, encoding);
                    var validationResults = await BarcodeReader.ReadAsync(barcode.ToBitmap());

                    if (validationResults.Any())
                    {
                        var validated = validationResults.First();
                        result.IsValid = true;
                        result.Format = validated.BarcodeType;
                        result.Value = validated.Value;
                        result.Confidence = validated.Confidence;

                        // Apply format-specific validation
                        if (_validators.ContainsKey(validated.BarcodeType))
                        {
                            result.PassesBusinessRules = _validators___PROTECTED_LINK_35___;
                        }

                        break;
                    }
                }
                catch { /* Try next format */ }
            }

            // Handle GS1-128 for supply chain applications
            if (!result.IsValid && IsGS1Format(scannedText))
            {
                result = await ValidateGS1BarcodeAsync(scannedText);
            }
        }
        catch (Exception ex)
        {
            result.Error = ex.Message;
        }

        return result;
    }

    private bool ValidateEAN13(string value)
    {
        // EAN-13 checksum validation
        if (value.Length != 13) return false;

        int sum = 0;
        for (int i = 0; i < 12; i++)
        {
            int digit = int.Parse(value[i].ToString());
            sum += (i % 2 == 0) ? digit : digit * 3;
        }

        int checkDigit = (10 - (sum % 10)) % 10;
        return checkDigit == int.Parse(value[12].ToString());
    }
}
$vbLabelText   $csharpLabel

對於多頁文檔,IronBarcode 可以讀取 PDF多頁 TIFF 文件中的條碼。

應用程式可以驗證哪些條碼格式?

此驗證方法支援所有主流的一維條碼格式二維條碼格式。 對於特殊應用,IronBarcode 也支援供應鏈管理中常用的MSI 條碼GS1-128格式。

如何根據掃描的輸入產生響應條碼?

應用程式何時應該根據掃描資料建立新的條碼?

將掃描資料轉換為可用於標籤、追蹤或庫存管理的新條碼,並具備生產就緒功能。 IronBarcode 的產生功能支援從各種資料類型建立條碼。 將條碼匯出為圖像PDFHTML串流

public class InventoryBarcodeGenerator
{
    private readonly string _labelPath = "labels";

    public InventoryBarcodeGenerator()
    {
        // Ensure proper licensing for production use
        IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
        System.IO.Directory.CreateDirectory(_labelPath);
    }

    public async Task<GeneratedBarcode> GenerateInventoryLabelAsync(string productCode, InventoryAction action)
    {
        try
        {
            // Generate structured inventory code
            var inventoryCode = GenerateStructuredCode(productCode, action);

            // Create high-quality barcode with production settings
            var barcode = BarcodeWriter.CreateBarcode(inventoryCode, BarcodeEncoding.Code128);

            // Apply enterprise styling
            barcode.ResizeTo(400, 120);
            barcode.SetMargins(10);
            barcode.AddAnnotationTextAboveBarcode(inventoryCode, IronSoftware.Drawing.Font.Arial, 12);
            barcode.ChangeBarCodeColor(IronSoftware.Drawing.Color.Black);

            // Add data matrix for redundancy in warehouse environments
            var dataMatrix = BarcodeWriter.CreateBarcode(inventoryCode, BarcodeEncoding.DataMatrix);
            dataMatrix.ResizeTo(100, 100);

            // Save with error handling
            var timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
            var fileName = $"{inventoryCode}_{timestamp}";

            // Save as multiple formats for flexibility
            await Task.Run(() =>
            {
                barcode.SaveAsPng($"{_labelPath}\\{fileName}.png");
                barcode.SaveAsPdf($"{_labelPath}\\{fileName}.pdf");
                barcode.SaveAsSvg($"{_labelPath}\\{fileName}.svg");
            });

            return new GeneratedBarcode
            {
                Code = inventoryCode,
                LinearBarcodePath = $"{_labelPath}\\{fileName}.png",
                DataMatrixPath = $"{_labelPath}\\{fileName}_dm.png",
                Timestamp = DateTime.UtcNow
            };
        }
        catch (Exception ex)
        {
            throw new BarcodeGenerationException($"Failed to generate barcode for {productCode}", ex);
        }
    }

    private string GenerateStructuredCode(string productCode, InventoryAction action)
    {
        // Implement GS1 Application Identifiers for enterprise compatibility
        var ai = action switch
        {
            InventoryAction.Receive => "10", // Batch/Lot number
            InventoryAction.Ship => "400", // Customer purchase order
            InventoryAction.Count => "37", // Quantity
            _ => "91" // Internal use
        };

        return $"({ai}){DateTime.Now:yyMMdd}{productCode}";
    }
}
public class InventoryBarcodeGenerator
{
    private readonly string _labelPath = "labels";

    public InventoryBarcodeGenerator()
    {
        // Ensure proper licensing for production use
        IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
        System.IO.Directory.CreateDirectory(_labelPath);
    }

    public async Task<GeneratedBarcode> GenerateInventoryLabelAsync(string productCode, InventoryAction action)
    {
        try
        {
            // Generate structured inventory code
            var inventoryCode = GenerateStructuredCode(productCode, action);

            // Create high-quality barcode with production settings
            var barcode = BarcodeWriter.CreateBarcode(inventoryCode, BarcodeEncoding.Code128);

            // Apply enterprise styling
            barcode.ResizeTo(400, 120);
            barcode.SetMargins(10);
            barcode.AddAnnotationTextAboveBarcode(inventoryCode, IronSoftware.Drawing.Font.Arial, 12);
            barcode.ChangeBarCodeColor(IronSoftware.Drawing.Color.Black);

            // Add data matrix for redundancy in warehouse environments
            var dataMatrix = BarcodeWriter.CreateBarcode(inventoryCode, BarcodeEncoding.DataMatrix);
            dataMatrix.ResizeTo(100, 100);

            // Save with error handling
            var timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
            var fileName = $"{inventoryCode}_{timestamp}";

            // Save as multiple formats for flexibility
            await Task.Run(() =>
            {
                barcode.SaveAsPng($"{_labelPath}\\{fileName}.png");
                barcode.SaveAsPdf($"{_labelPath}\\{fileName}.pdf");
                barcode.SaveAsSvg($"{_labelPath}\\{fileName}.svg");
            });

            return new GeneratedBarcode
            {
                Code = inventoryCode,
                LinearBarcodePath = $"{_labelPath}\\{fileName}.png",
                DataMatrixPath = $"{_labelPath}\\{fileName}_dm.png",
                Timestamp = DateTime.UtcNow
            };
        }
        catch (Exception ex)
        {
            throw new BarcodeGenerationException($"Failed to generate barcode for {productCode}", ex);
        }
    }

    private string GenerateStructuredCode(string productCode, InventoryAction action)
    {
        // Implement GS1 Application Identifiers for enterprise compatibility
        var ai = action switch
        {
            InventoryAction.Receive => "10", // Batch/Lot number
            InventoryAction.Ship => "400", // Customer purchase order
            InventoryAction.Count => "37", // Quantity
            _ => "91" // Internal use
        };

        return $"({ai}){DateTime.Now:yyMMdd}{productCode}";
    }
}
$vbLabelText   $csharpLabel

對於特殊需求,開發人員可以建立 1-BPP 條碼影像以進行高對比列印,或在現有 PDF 上蓋章條碼

產生的條碼有哪些自訂選項?

IronBarcode 提供豐富的自訂選項,包括顏色變更邊距設定以及帶有徽標嵌入的二維碼樣式

![Windows Forms 應用程式介面,示範 IronBarcode 的雙條碼產生功能。 介面顯示已成功產生庫存編號為"INV-20250917-helloworld"的 Code 128 線性條碼和二維碼。 頂部的輸入欄位允許使用者輸入自訂庫存代碼,並有一個"產生"按鈕來建立條碼。 成功訊息"專案處理成功 - 已產生標籤"確認操作已完成。 Code 128 條碼被標記為主要的庫存追蹤格式,而下方的二維碼則被標記為行動友善替代方案。該應用程式採用專業的灰色背景和清晰的視覺層次結構,展示了 IronBarcode 如何幫助開發人員創建多格式條碼生成系統,以實現完整的庫存管理。

如何建立一個完整的條碼掃描應用程式?

生產就緒的掃描器實施方案是什麼樣的?

這是一個企業級實現,具有完整的錯誤處理和效能最佳化功能。 這種方法利用IronBarcode 的效能特性非同步功能來提高吞吐量:

using IronBarCode;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EnterpriseBarcodeScanner
{
    public partial class HighVolumeScanner : Form
    {
        private readonly ConcurrentQueue<ScanData> _scanQueue = new();
        private readonly SemaphoreSlim _processingSemaphore;
        private readonly CancellationTokenSource _cancellationTokenSource = new();
        private IScannerInput _activeScanner;
        private int _maxConcurrentProcessing = Environment.ProcessorCount;

        public HighVolumeScanner()
        {
            InitializeComponent();
            _processingSemaphore = new SemaphoreSlim(_maxConcurrentProcessing);
            InitializeScanner();
            StartProcessingQueue();
        }

        private void InitializeScanner()
        {
            // Auto-detect scanner type
            if (SerialPort.GetPortNames().Any(p => p.Contains("COM")))
            {
                _activeScanner = new SerialPortScanner("COM3", 115200);
            }
            else
            {
                _activeScanner = new KeyboardWedgeScanner(txtScanner);
            }

            _activeScanner.BarcodeScanned += OnBarcodeScanned;
            _activeScanner.StartListening();
        }

        private void OnBarcodeScanned(object sender, string barcode)
        {
            // Queue for async processing to maintain scanner responsiveness
            _scanQueue.Enqueue(new ScanData 
            { 
                RawData = barcode, 
                ScanTime = DateTime.UtcNow 
            });
        }

        private async void StartProcessingQueue()
        {
            while (!_cancellationTokenSource.Token.IsCancellationRequested)
            {
                if (_scanQueue.TryDequeue(out var scanData))
                {
                    await _processingSemaphore.WaitAsync();

                    _ = Task.Run(async () =>
                    {
                        try
                        {
                            await ProcessScanAsync(scanData);
                        }
                        finally
                        {
                            _processingSemaphore.Release();
                        }
                    }, _cancellationTokenSource.Token);
                }
                else
                {
                    await Task.Delay(10); // Prevent CPU spinning
                }
            }
        }

        private async Task ProcessScanAsync(ScanData scanData)
        {
            try
            {
                // Validate with timeout for performance
                using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2));
                var validationTask = ValidateAndProcessBarcodeAsync(scanData.RawData);
                var completedTask = await Task.WhenAny(validationTask, Task.Delay(Timeout.Infinite, cts.Token));

                if (completedTask == validationTask)
                {
                    var result = await validationTask;

                    if (result.Success)
                    {
                        // Update UI thread-safe
                        BeginInvoke(new Action(() =>
                        {
                            AddToInventory(result);
                            GenerateLabelsIfNeeded(result);
                        }));
                    }
                    else
                    {
                        LogScanError(scanData, result.Error);
                    }
                }
                else
                {
                    LogScanTimeout(scanData);
                }
            }
            catch (Exception ex)
            {
                LogCriticalError(ex, scanData);
            }
        }

        private async Task<ProcessingResult> ValidateAndProcessBarcodeAsync(string rawData)
        {
            // Implement smart caching for repeated scans
            if (BarcodeCache.TryGetCached(rawData, out var cachedResult))
            {
                return cachedResult;
            }

            // Use IronBarcode with optimized settings
            var barcodeOptions = new BarcodeReaderOptions
            {
                Speed = ReadingSpeed.Balanced,
                ExpectMultipleBarcodes = false,
                ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode,
                MaxParallelThreads = 1 // Single barcode, no need for parallel
            };

            // Generate and validate
            var testBarcode = BarcodeWriter.CreateBarcode(rawData, BarcodeEncoding.Code128);
            var results = await BarcodeReader.ReadAsync(testBarcode.ToBitmap(), barcodeOptions);

            var result = new ProcessingResult
            {
                Success = results.Any(),
                BarcodeData = results.FirstOrDefault(),
                ProcessingTime = DateTime.UtcNow
            };

            BarcodeCache.Add(rawData, result);
            return result;
        }
    }
}
using IronBarCode;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EnterpriseBarcodeScanner
{
    public partial class HighVolumeScanner : Form
    {
        private readonly ConcurrentQueue<ScanData> _scanQueue = new();
        private readonly SemaphoreSlim _processingSemaphore;
        private readonly CancellationTokenSource _cancellationTokenSource = new();
        private IScannerInput _activeScanner;
        private int _maxConcurrentProcessing = Environment.ProcessorCount;

        public HighVolumeScanner()
        {
            InitializeComponent();
            _processingSemaphore = new SemaphoreSlim(_maxConcurrentProcessing);
            InitializeScanner();
            StartProcessingQueue();
        }

        private void InitializeScanner()
        {
            // Auto-detect scanner type
            if (SerialPort.GetPortNames().Any(p => p.Contains("COM")))
            {
                _activeScanner = new SerialPortScanner("COM3", 115200);
            }
            else
            {
                _activeScanner = new KeyboardWedgeScanner(txtScanner);
            }

            _activeScanner.BarcodeScanned += OnBarcodeScanned;
            _activeScanner.StartListening();
        }

        private void OnBarcodeScanned(object sender, string barcode)
        {
            // Queue for async processing to maintain scanner responsiveness
            _scanQueue.Enqueue(new ScanData 
            { 
                RawData = barcode, 
                ScanTime = DateTime.UtcNow 
            });
        }

        private async void StartProcessingQueue()
        {
            while (!_cancellationTokenSource.Token.IsCancellationRequested)
            {
                if (_scanQueue.TryDequeue(out var scanData))
                {
                    await _processingSemaphore.WaitAsync();

                    _ = Task.Run(async () =>
                    {
                        try
                        {
                            await ProcessScanAsync(scanData);
                        }
                        finally
                        {
                            _processingSemaphore.Release();
                        }
                    }, _cancellationTokenSource.Token);
                }
                else
                {
                    await Task.Delay(10); // Prevent CPU spinning
                }
            }
        }

        private async Task ProcessScanAsync(ScanData scanData)
        {
            try
            {
                // Validate with timeout for performance
                using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2));
                var validationTask = ValidateAndProcessBarcodeAsync(scanData.RawData);
                var completedTask = await Task.WhenAny(validationTask, Task.Delay(Timeout.Infinite, cts.Token));

                if (completedTask == validationTask)
                {
                    var result = await validationTask;

                    if (result.Success)
                    {
                        // Update UI thread-safe
                        BeginInvoke(new Action(() =>
                        {
                            AddToInventory(result);
                            GenerateLabelsIfNeeded(result);
                        }));
                    }
                    else
                    {
                        LogScanError(scanData, result.Error);
                    }
                }
                else
                {
                    LogScanTimeout(scanData);
                }
            }
            catch (Exception ex)
            {
                LogCriticalError(ex, scanData);
            }
        }

        private async Task<ProcessingResult> ValidateAndProcessBarcodeAsync(string rawData)
        {
            // Implement smart caching for repeated scans
            if (BarcodeCache.TryGetCached(rawData, out var cachedResult))
            {
                return cachedResult;
            }

            // Use IronBarcode with optimized settings
            var barcodeOptions = new BarcodeReaderOptions
            {
                Speed = ReadingSpeed.Balanced,
                ExpectMultipleBarcodes = false,
                ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode,
                MaxParallelThreads = 1 // Single barcode, no need for parallel
            };

            // Generate and validate
            var testBarcode = BarcodeWriter.CreateBarcode(rawData, BarcodeEncoding.Code128);
            var results = await BarcodeReader.ReadAsync(testBarcode.ToBitmap(), barcodeOptions);

            var result = new ProcessingResult
            {
                Success = results.Any(),
                BarcodeData = results.FirstOrDefault(),
                ProcessingTime = DateTime.UtcNow
            };

            BarcodeCache.Add(rawData, result);
            return result;
        }
    }
}
$vbLabelText   $csharpLabel

為了提高效能,可以實施裁切區域,將掃描重點放在特定的影像區域。 條碼閱讀器設定允許針對不同文件類型進行微調。

團隊如何實施備用機制?

這款企業級掃描應用程式實現了幾個關鍵模式:

1.非同步佇列處理:使用非同步操作防止 UI 阻塞 2.並發處理:使用多個執行緒進行並行驗證 3.智慧型快取:減少頻繁項的冗餘處理 4.效能監控:使用讀取速度選項追蹤掃描速率 5.靈活的掃描器支援:自動偵測可用硬件

*無效格式:*捕獲 BarcodeWriter 遇到不支援的資料時拋出的異常 掃描器斷開連線:實現文字方塊焦點管理以處理掃描器移除操作 資料驗證:使用 IronBarcode 的特定格式編碼,以確保資料相容性 條碼產生失敗:**將條碼產生過程封裝在 try-catch 區塊中。 *超時處理:考慮實現按鍵計時,以區分掃描器輸入和鍵盤輸入。

![專業 Windows Forms 條碼掃描器應用程序,展示了 IronBarcode 的即時庫存追蹤功能。 介面採用簡潔的雙面板設計,搭配精緻的深藍色標題列。 左側面板顯示掃描歷史記錄列表,其中顯示了四個成功掃描的庫存項目(INV-001 至 INV-004),並帶有精確的時間戳和掃描狀態指示器。 每個項目都包含詳細的元數據,例如條碼類型和置信度。 右側面板顯示動態產生的摘要條碼,其中顯示"商品數量:4",並具有專業的樣式和適當的邊距。 底部的操作按鈕包括"清除清單"、"匯出資料"和"列印標籤",用於完整的庫存管理。 狀態列顯示"掃描器:已連線" | 模式:連續 | 上次掃描時間:2 秒前,這展示了 IronBarcode 為生產庫存系統提供的即時監控功能和專業的企業級設計。

條碼掃描器專案的下一步是什麼?

IronBarcode將簡單的 USB 條碼掃描轉換為智慧型資料處理應用。 透過將硬體掃描器輸入與 IronBarcode 的驗證產生和格式轉換功能結合,開發人員可以為任何行業建立可靠的掃描解決方案。 該程式庫對非同步操作多執行緒的支援確保應用程式能夠隨著業務需求的成長而擴展。

對於雲端部署,IronBarcode 為AWS LambdaAzure Functions提供了出色的支持,從而能夠大規模地進行無伺服器條碼處理。 該函式庫與Docker 容器無縫集成,可用於微服務架構。

在實施企業庫存系統時,請考慮以下架構模式:

1.微服務:使用Docker 上的 IronBarcode將掃描功能部署為獨立服務。 2.行動整合:擴展到支援AndroidiOS 的設備

  1. Web 應用程式:建立基於瀏覽器的掃描功能,並整合 Blazor。 4.高可用性:透過多種讀取方式實現冗餘

立即開始免費試用,在 C# 應用程式中實現專業的條碼掃描功能。 如需相關功能,請探索IronOCR ,它具有文字辨識功能,可與條碼掃描工作流程相輔相成。

常見問題解答

IronBarcode是什麼?它與USB條碼掃描器有何關係?

IronBarcode 是一個庫,它使開發人員能夠建立功能強大的 C# 應用程序,用於 USB 條碼掃描。它提供條碼驗證、資料提取和條碼生成等功能。

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 以及提供的程式碼範例和文件來指導您的開發流程。

柯蒂斯·週
技術撰稿人

Curtis Chau擁有卡爾頓大學電腦科學學士學位,專長於前端開發,精通Node.js、TypeScript、JavaScript和React。他熱衷於打造直覺美觀的使用者介面,喜歡使用現代框架,並擅長撰寫結構清晰、視覺效果出色的使用者手冊。

除了開發工作之外,柯蒂斯對物聯網 (IoT) 也抱有濃厚的興趣,致力於探索硬體和軟體整合的創新方法。閒暇時,他喜歡玩遊戲和製作 Discord 機器人,將他對科技的熱愛與創造力結合。