Jak odczytywać i skanować kody kreskowe w C# używając NET MAUI
Migrating fromInfragisticsBarCode to IronBarcode
Większość migracji kodów kreskowychInfragisticsma miejsce, ponieważ zespół potrzebował odczytu kodów kreskowych w projekcie, w którym dostępna była tylko generacja — WinForms, .NET Core lub dowolny projekt poza WPF — lub ponieważ sterowane zdarzeniami API czytnika WPF okazało się zbyt niestabilne do użytku produkcyjnego. Wzorzec mostka TaskCompletionSource, wspólne pole _result, które czyni równoczesne wywołania niebezpiecznymi, oraz ciche niepowodzenia spowodowane brakiem flag SymbologyType to częste powody, dla których zespoły szukają alternatyw.
Ten przewodnik przeprowadza użytkownika przez cały proces migracji: usuwanie pakietów kodów kreskowych Infragistics, zastępowanie kodu generującego i odczytującego zarówno w kontekście WinForms, jak i WPF oraz dodawanie funkcjonalności BarCode do typów projektów, w którychInfragisticsnie zapewniało żadnego wsparcia.
Szybki start
Krok 1: Usuń pakiety BarCode Infragistics
Usuń pakiety NuGet z kodami BarCodeInfragisticsze swojego projektu. W zależności od tego, jakich celów używałeś:
# WinForms generation package
dotnet remove package Infragistics.WinForms.Barcode
# WPF reading package
dotnet remove package Infragistics.WPF.BarcodeReader
# WinForms generation package
dotnet remove package Infragistics.WinForms.Barcode
# WPF reading package
dotnet remove package Infragistics.WPF.BarcodeReader
Jeśli plik projektu odwołuje się do obu, usuń oba. Usunięcie pakietów związanych z kodami kreskowymi nie ma wpływu na licencjęInfragisticsUltimate, jeśli korzystasz z innych komponentów Infragistics.
Krok 2: Zainstaluj IronBarcode
dotnet add package IronBarcode
dotnet add package IronBarcode
IronBarcode to pojedynczy pakiet, który działa w środowiskach WinForms, WPF, ASP.NET Core, konsoli, Blazor Server, Docker,Azure Functionsi AWS Lambda. Nie ma potrzeby tworzenia oddzielnych pakietów dla poszczególnych frameworków.
Krok 3: Aktualizacja przestrzeni nazw
Zamień przestrzenie nazw kodów kreskowychInfragisticsna IronBarCode (duże B, duże C):
// Remove these:
// using Infragistics.Win.UltraWinBarcode;
// using Infragistics.Controls.Barcodes;
// using System.Windows.Media.Imaging; // if only used for barcode BitmapImage loading
// Add this:
using IronBarCode;
// Remove these:
// using Infragistics.Win.UltraWinBarcode;
// using Infragistics.Controls.Barcodes;
// using System.Windows.Media.Imaging; // if only used for barcode BitmapImage loading
// Add this:
using IronBarCode;
Imports IronBarCode
Krok 4: Zainicjuj licencję
Dodaj inicjalizację licencji raz przy starcie aplikacji — Program.cs, App.xaml.cs lub twój rdzeń kompozycji DI:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Przykłady migracji kodu
Generowanie WinForms: UltraWinBarcode do BarcodeWriter
Wzorzec generacji WinForms mapuje się czysto na BarcodeWriter IronBarcode:
Przed (Infragistics WinForms):
using Infragistics.Win.UltraWinBarcode;
var barcode = new UltraWinBarcode();
barcode.Symbology = Symbology.Code128;
barcode.Data = "ITEM-12345";
barcode.SaveTo(outputPath);
using Infragistics.Win.UltraWinBarcode;
var barcode = new UltraWinBarcode();
barcode.Symbology = Symbology.Code128;
barcode.Data = "ITEM-12345";
barcode.SaveTo(outputPath);
Imports Infragistics.Win.UltraWinBarcode
Dim barcode As New UltraWinBarcode()
barcode.Symbology = Symbology.Code128
barcode.Data = "ITEM-12345"
barcode.SaveTo(outputPath)
Po (IronBarcode):
// NuGet: dotnet add package IronBarcode
using IronBarCode;
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128)
.SaveAsPng(outputPath);
// NuGet: dotnet add package IronBarcode
using IronBarCode;
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128)
.SaveAsPng(outputPath);
Imports IronBarCode
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128) _
.SaveAsPng(outputPath)
Wartość enum Symbology wInfragisticsprzechodzi do enum BarcodeEncoding, który jest parametrem dla CreateBarcode() zamiast przypisania właściwości. Dane stają się pierwszym argumentem. SaveTo() staje się .SaveAsPng(), .SaveAsJpeg(), .SaveAsSvg() lub .SaveAsPdf() w zależności od formatu wyjściowego.
Jeśli przed zapisaniem konieczne jest zmniejszenie rozmiaru BarCODE:
using IronBarCode;
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128)
.ResizeTo(400, 100)
.SaveAsPng(outputPath);
using IronBarCode;
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128)
.ResizeTo(400, 100)
.SaveAsPng(outputPath);
Imports IronBarCode
BarcodeWriter.CreateBarcode("ITEM-12345", BarcodeEncoding.Code128) _
.ResizeTo(400, 100) _
.SaveAsPng(outputPath)
Czytanie sterowane zdarzeniami w WPF: klasa usługi w dwóch wierszach
Jest to najbardziej znacząca redukcja w ramach migracji. Wzorzec odczytuInfragisticsWPF wymaga klasy pełnej obsługi:
Przed (Infragistics WPF — ~35 wierszy):
using Infragistics.Controls.Barcodes;
using System.Windows.Media.Imaging;
private BarcodeReader _reader;
private TaskCompletionSource<string> _result;
public InfragisticsBarcodeService()
{
_reader = new BarcodeReader();
_reader.DecodeComplete += OnDecodeComplete;
}
public async Task<string> ReadBarcodeAsync(string imagePath)
{
_result = new TaskCompletionSource<string>();
var bitmap = new BitmapImage(new Uri(imagePath, UriKind.Absolute));
_reader.SymbologyTypes = Symbology.Code128 |
Symbology.Code39 |
Symbology.QRCode |
Symbology.EAN8 |
Symbology.EAN13 |
Symbology.UpcA |
Symbology.Interleaved2Of5;
_reader.Decode(bitmap);
return await _result.Task;
}
private void OnDecodeComplete(object sender, ReaderDecodeArgs e)
{
_result?.TrySetResult(e.Value ?? "No barcode found");
}
public void Dispose()
{
if (_reader != null)
{
_reader.DecodeComplete -= OnDecodeComplete;
_reader = null;
}
}
using Infragistics.Controls.Barcodes;
using System.Windows.Media.Imaging;
private BarcodeReader _reader;
private TaskCompletionSource<string> _result;
public InfragisticsBarcodeService()
{
_reader = new BarcodeReader();
_reader.DecodeComplete += OnDecodeComplete;
}
public async Task<string> ReadBarcodeAsync(string imagePath)
{
_result = new TaskCompletionSource<string>();
var bitmap = new BitmapImage(new Uri(imagePath, UriKind.Absolute));
_reader.SymbologyTypes = Symbology.Code128 |
Symbology.Code39 |
Symbology.QRCode |
Symbology.EAN8 |
Symbology.EAN13 |
Symbology.UpcA |
Symbology.Interleaved2Of5;
_reader.Decode(bitmap);
return await _result.Task;
}
private void OnDecodeComplete(object sender, ReaderDecodeArgs e)
{
_result?.TrySetResult(e.Value ?? "No barcode found");
}
public void Dispose()
{
if (_reader != null)
{
_reader.DecodeComplete -= OnDecodeComplete;
_reader = null;
}
}
Imports Infragistics.Controls.Barcodes
Imports System.Windows.Media.Imaging
Imports System.Threading.Tasks
Private _reader As BarcodeReader
Private _result As TaskCompletionSource(Of String)
Public Sub New()
_reader = New BarcodeReader()
AddHandler _reader.DecodeComplete, AddressOf OnDecodeComplete
End Sub
Public Async Function ReadBarcodeAsync(imagePath As String) As Task(Of String)
_result = New TaskCompletionSource(Of String)()
Dim bitmap As New BitmapImage(New Uri(imagePath, UriKind.Absolute))
_reader.SymbologyTypes = Symbology.Code128 Or
Symbology.Code39 Or
Symbology.QRCode Or
Symbology.EAN8 Or
Symbology.EAN13 Or
Symbology.UpcA Or
Symbology.Interleaved2Of5
_reader.Decode(bitmap)
Return Await _result.Task
End Function
Private Sub OnDecodeComplete(sender As Object, e As ReaderDecodeArgs)
_result?.TrySetResult(If(e.Value, "No barcode found"))
End Sub
Public Sub Dispose()
If _reader IsNot Nothing Then
RemoveHandler _reader.DecodeComplete, AddressOf OnDecodeComplete
_reader = Nothing
End If
End Sub
Po (IronBarcode — 2 wiersze):
using IronBarCode;
var results = BarcodeReader.Read(imagePath);
return results.FirstOrDefault()?.Value ?? "No barcode found";
using IronBarCode;
var results = BarcodeReader.Read(imagePath);
return results.FirstOrDefault()?.Value ?? "No barcode found";
Imports IronBarCode
Dim results = BarcodeReader.Read(imagePath)
Return If(results.FirstOrDefault()?.Value, "No barcode found")
Cała klasa usługi — zarządzanie instancją, okablowanie zdarzeń, TaskCompletionSource, ładowanie BitmapImage, Dispose() — zniknęły. BarcodeReader.Read() jest synchroniczna, statyczna i akceptuje bezpośrednio ścieżkę pliku w postaci ciągu znaków.
Jeśli zwracałbyś również typ symboliki:
using IronBarCode;
var results = BarcodeReader.Read(imagePath);
var first = results.FirstOrDefault();
if (first != null)
{
Console.WriteLine($"Value: {first.Value}, Format: {first.Format}");
}
using IronBarCode;
var results = BarcodeReader.Read(imagePath);
var first = results.FirstOrDefault();
if (first != null)
{
Console.WriteLine($"Value: {first.Value}, Format: {first.Format}");
}
Imports IronBarCode
Dim results = BarcodeReader.Read(imagePath)
Dim first = results.FirstOrDefault()
If first IsNot Nothing Then
Console.WriteLine($"Value: {first.Value}, Format: {first.Format}")
End If
result.Value zastępuje e.Value. result.Format zastępuje e.Symbology.
Dodanie obsługi WinForms (wcześniej niemożliwe)
Jeśli pracowałeś nad projektem WinForms, który obsługiwał tylko generowanie, teraz w tym samym pakiecie dostępna jest również funkcja odczytu:
using IronBarCode;
// In a WinForms button handler or service method — same API as WPF or ASP.NET Core
var results = BarcodeReader.Read(imagePath);
foreach (var result in results)
{
MessageBox.Show($"Found: {result.Value} ({result.Format})");
}
using IronBarCode;
// In a WinForms button handler or service method — same API as WPF or ASP.NET Core
var results = BarcodeReader.Read(imagePath);
foreach (var result in results)
{
MessageBox.Show($"Found: {result.Value} ({result.Format})");
}
Imports IronBarCode
' In a WinForms button handler or service method — same API as WPF or ASP.NET Core
Dim results = BarcodeReader.Read(imagePath)
For Each result In results
MessageBox.Show($"Found: {result.Value} ({result.Format})")
Next
Brak dodatkowych pakietów, żadnej specyficznej dla frameworka konfiguracji. To samo wywołanie BarcodeReader.Read() działa w WinForms jak i w WPF.
Punkt końcowyASP.NET Core(wcześniej niemożliwy)
Generowanie i odczytywanie BarCODE w kontrolerzeASP.NET Corenie było możliwe przy użyciu pakietów Infragistics. Dzięki IronBarcode:
using IronBarCode;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/barcode")]
public class BarcodeController : ControllerBase
{
[HttpPost("read")]
public IActionResult ReadBarcode(IFormFile imageFile)
{
using var stream = imageFile.OpenReadStream();
var results = BarcodeReader.Read(stream);
var values = results.Select(r => new { r.Value, Format = r.Format.ToString() });
return Ok(values);
}
[HttpGet("generate")]
public IActionResult GenerateBarcode([FromQuery] string data)
{
var bytes = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ResizeTo(400, 100)
.ToPngBinaryData();
return File(bytes, "image/png");
}
}
using IronBarCode;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/barcode")]
public class BarcodeController : ControllerBase
{
[HttpPost("read")]
public IActionResult ReadBarcode(IFormFile imageFile)
{
using var stream = imageFile.OpenReadStream();
var results = BarcodeReader.Read(stream);
var values = results.Select(r => new { r.Value, Format = r.Format.ToString() });
return Ok(values);
}
[HttpGet("generate")]
public IActionResult GenerateBarcode([FromQuery] string data)
{
var bytes = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128)
.ResizeTo(400, 100)
.ToPngBinaryData();
return File(bytes, "image/png");
}
}
Imports IronBarCode
Imports Microsoft.AspNetCore.Mvc
<ApiController>
<Route("api/barcode")>
Public Class BarcodeController
Inherits ControllerBase
<HttpPost("read")>
Public Function ReadBarcode(imageFile As IFormFile) As IActionResult
Using stream = imageFile.OpenReadStream()
Dim results = BarcodeReader.Read(stream)
Dim values = results.Select(Function(r) New With {Key .Value = r.Value, Key .Format = r.Format.ToString()})
Return Ok(values)
End Using
End Function
<HttpGet("generate")>
Public Function GenerateBarcode(<FromQuery> data As String) As IActionResult
Dim bytes = BarcodeWriter.CreateBarcode(data, BarcodeEncoding.Code128) _
.ResizeTo(400, 100) _
.ToPngBinaryData()
Return File(bytes, "image/png")
End Function
End Class
BarcodeReader.Read() akceptuje Stream bezpośrednio — nie ma potrzeby najpierw zapisywania uploadu na dysk.
Odczytywanie BarCodes z plików PDF
IronBarcode odczytuje kody kreskowe z dokumentów PDF w sposób natywny — nie wymaga oddzielnego pakietu:
using IronBarCode;
// Read all barcodes from every page of a PDF
var results = BarcodeReader.Read("document.pdf");
foreach (var result in results)
{
Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.Format})");
}
using IronBarCode;
// Read all barcodes from every page of a PDF
var results = BarcodeReader.Read("document.pdf");
foreach (var result in results)
{
Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.Format})");
}
Imports IronBarCode
' Read all barcodes from every page of a PDF
Dim results = BarcodeReader.Read("document.pdf")
For Each result In results
Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.Format})")
Next
Infragistics nie miał odpowiednika — odczyt BarCode'ów z plików PDF wymagał zewnętrznej konwersji stron PDF na obrazy przed skanowaniem.
Przetwarzanie wsadowe: od sekwencyjnego do równoległego
Przed (Infragistics — sekwencyjny, niezabezpieczony pod kątem współbieżności dla równoległości):
// Must process one at a time — shared _result field is not thread-safe
var service = new InfragisticsBarcodeService();
var results = new List<string>();
foreach (var file in imageFiles)
{
var value = await service.ReadBarcodeAsync(file);
results.Add(value);
}
service.Dispose();
// Must process one at a time — shared _result field is not thread-safe
var service = new InfragisticsBarcodeService();
var results = new List<string>();
foreach (var file in imageFiles)
{
var value = await service.ReadBarcodeAsync(file);
results.Add(value);
}
service.Dispose();
Imports System.Collections.Generic
' Must process one at a time — shared _result field is not thread-safe
Dim service As New InfragisticsBarcodeService()
Dim results As New List(Of String)()
For Each file In imageFiles
Dim value As String = Await service.ReadBarcodeAsync(file)
results.Add(value)
Next
service.Dispose()
Po (IronBarcode — równoległe, bezpieczne dla wątków):
using IronBarCode;
// Option 1: pass an array directly —IronBarcode handles parallelization internally
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
var results = BarcodeReader.Read(imageFiles.ToArray(), options);
foreach (var result in results)
{
Console.WriteLine($"{result.Value} ({result.Format})");
}
using IronBarCode;
// Option 1: pass an array directly —IronBarcode handles parallelization internally
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = true,
MaxParallelThreads = 4
};
var results = BarcodeReader.Read(imageFiles.ToArray(), options);
foreach (var result in results)
{
Console.WriteLine($"{result.Value} ({result.Format})");
}
Imports IronBarCode
' Option 1: pass an array directly —IronBarcode handles parallelization internally
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = True,
.MaxParallelThreads = 4
}
Dim results = BarcodeReader.Read(imageFiles.ToArray(), options)
For Each result In results
Console.WriteLine($"{result.Value} ({result.Format})")
Next
using IronBarCode;
using System.Collections.Concurrent;
// Option 2: Parallel.ForEach — static BarcodeReader.Read is thread-safe
var allValues = new ConcurrentBag<string>();
Parallel.ForEach(imageFiles, file =>
{
var results = BarcodeReader.Read(file);
foreach (var r in results)
allValues.Add(r.Value);
});
using IronBarCode;
using System.Collections.Concurrent;
// Option 2: Parallel.ForEach — static BarcodeReader.Read is thread-safe
var allValues = new ConcurrentBag<string>();
Parallel.ForEach(imageFiles, file =>
{
var results = BarcodeReader.Read(file);
foreach (var r in results)
allValues.Add(r.Value);
});
Imports IronBarCode
Imports System.Collections.Concurrent
' Option 2: Parallel.ForEach — static BarcodeReader.Read is thread-safe
Dim allValues As New ConcurrentBag(Of String)()
Parallel.ForEach(imageFiles, Sub(file)
Dim results = BarcodeReader.Read(file)
For Each r In results
allValues.Add(r.Value)
Next
End Sub)
Usunięcie wzorca Dispose
Jeśli twój kod zawierał implementacje IDisposable wokółInfragisticsBarcodeReader, można je całkowicie usunąć. BarcodeReaderIronBarcode jest klasą statyczną. Nie ma żadnej instancji do utworzenia, żadnego obsługi zdarzeń do odłączenia i żadnego wywołania Dispose().
// Before: service registered as IDisposable in DI container
services.AddScoped<InfragisticsBarcodeService>(); // implements IDisposable
// After: no registration needed — use static method directly, or wrap in thin service if preferred
// services.AddScoped<IBarcodeService, IronBarcodeService>();
// Before: service registered as IDisposable in DI container
services.AddScoped<InfragisticsBarcodeService>(); // implements IDisposable
// After: no registration needed — use static method directly, or wrap in thin service if preferred
// services.AddScoped<IBarcodeService, IronBarcodeService>();
' Before: service registered as IDisposable in DI container
services.AddScoped(Of InfragisticsBarcodeService)() ' implements IDisposable
' After: no registration needed — use static method directly, or wrap in thin service if preferred
' services.AddScoped(Of IBarcodeService, IronBarcodeService)()
Prosta usługa typu thin wrapper do celów DI jest następująca:
using IronBarCode;
public class BarcodeService
{
public IEnumerable<string> Read(string path)
=> BarcodeReader.Read(path).Select(r => r.Value);
public byte[] Generate(string data, BarcodeEncoding encoding)
=> BarcodeWriter.CreateBarcode(data, encoding).ToPngBinaryData();
}
using IronBarCode;
public class BarcodeService
{
public IEnumerable<string> Read(string path)
=> BarcodeReader.Read(path).Select(r => r.Value);
public byte[] Generate(string data, BarcodeEncoding encoding)
=> BarcodeWriter.CreateBarcode(data, encoding).ToPngBinaryData();
}
Imports IronBarCode
Public Class BarcodeService
Public Function Read(path As String) As IEnumerable(Of String)
Return BarcodeReader.Read(path).Select(Function(r) r.Value)
End Function
Public Function Generate(data As String, encoding As BarcodeEncoding) As Byte()
Return BarcodeWriter.CreateBarcode(data, encoding).ToPngBinaryData()
End Function
End Class
Brak wstrzykiwania konstruktorów, brak Dispose(), brak zarządzania zdarzeniami.
Typowe problemy związane z migracją
Usunięto flagi typu symboliki
Właściwość SymbologyTypes w czytnikuInfragisticsWPF wymagała wskazania każdego formatu kodu kreskowego, który chciano obsługiwać.IronBarcode nie ma sobie równych — automatycznie wykrywa wszystkie ponad 50 obsługiwanych formatów przy każdym odczycie.
To ma ważny efekt uboczny: jeśli wcześniej konkretne formaty kodów kreskowych nie były wykrywane, ponieważ brakowało ich flagi SymbologyType na liście,IronBarcode teraz je znajdzie. W środowisku produkcyjnym mogą pojawić się wartości BarCode, które wcześniej były pomijane bez powiadomienia. To jest prawidłowe zachowanie — te barcody zawsze tam były.
Jeśli chcesz ograniczyć, które formaty są zwracane (ze względów wydajnościowych lub niejednoznaczności), BarcodeReaderOptions to obsługuje:
using IronBarCode;
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = false
};
var results = BarcodeReader.Read(imagePath, options);
using IronBarCode;
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced,
ExpectMultipleBarcodes = false
};
var results = BarcodeReader.Read(imagePath, options);
Imports IronBarCode
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced,
.ExpectMultipleBarcodes = False
}
Dim results = BarcodeReader.Read(imagePath, options)
Nie jest wymagane ładowanie obrazu bitmapowego
CzytnikInfragisticsWPF wymagał ładowania obrazów jako obiekty BitmapSource przez new BitmapImage(new Uri(path, UriKind.Absolute)).IronBarcode akceptuje bezpośrednio ciągi znaków ścieżek plików, tablice bajtów i strumienie:
// All of these work — no BitmapImage conversion needed
BarcodeReader.Read("path/to/image.png");
BarcodeReader.Read(File.ReadAllBytes("path/to/image.png"));
BarcodeReader.Read(File.OpenRead("path/to/image.png"));
// All of these work — no BitmapImage conversion needed
BarcodeReader.Read("path/to/image.png");
BarcodeReader.Read(File.ReadAllBytes("path/to/image.png"));
BarcodeReader.Read(File.OpenRead("path/to/image.png"));
' All of these work — no BitmapImage conversion needed
BarcodeReader.Read("path/to/image.png")
BarcodeReader.Read(File.ReadAllBytes("path/to/image.png"))
BarcodeReader.Read(File.OpenRead("path/to/image.png"))
Możesz usunąć wszelkie importy using System.Windows.Media.Imaging;, które były używane tylko do ładowania obrazów związanych z kodami kreskowymi.
Wzorzec TaskCompletionSource usunięty
Pole TaskCompletionSource<string>, które łączyło oparty na zdarzeniach callback DecodeComplete z kodem asynchronicznym, całkowicie zniknęło. BarcodeReader.Read() jest synchroniczna i zwraca swoje wyniki bezpośrednio.
Jeśli twój kod wywołujący był await service.ReadBarcodeAsync(path), możesz uprościć do:
// Before
var value = await service.ReadBarcodeAsync(imagePath);
// After
var value = BarcodeReader.Read(imagePath).FirstOrDefault()?.Value ?? "No barcode found";
// Before
var value = await service.ReadBarcodeAsync(imagePath);
// After
var value = BarcodeReader.Read(imagePath).FirstOrDefault()?.Value ?? "No barcode found";
Jeśli chcesz zachować interfejs asynchroniczny dla wywołujących na dalszym etapie bez blokowania wątku:
public Task<string> ReadBarcodeAsync(string imagePath)
{
return Task.Run(() =>
{
var results = BarcodeReader.Read(imagePath);
return results.FirstOrDefault()?.Value ?? "No barcode found";
});
}
public Task<string> ReadBarcodeAsync(string imagePath)
{
return Task.Run(() =>
{
var results = BarcodeReader.Read(imagePath);
return results.FirstOrDefault()?.Value ?? "No barcode found";
});
}
Option Strict On
Public Function ReadBarcodeAsync(imagePath As String) As Task(Of String)
Return Task.Run(Function()
Dim results = BarcodeReader.Read(imagePath)
Return If(results.FirstOrDefault()?.Value, "No barcode found")
End Function)
End Function
Zmiany nazw właściwości
| Infragistics | IronBarcode |
|---|---|
e.Value (w ReaderDecodeArgs) |
result.Value |
e.Symbology (w ReaderDecodeArgs) |
result.Format |
barcode.Data |
Pierwszy argument BarcodeWriter.CreateBarcode() |
barcode.Symbology = Symbology.Code128 |
BarcodeEncoding.Code128 (parametr) |
barcode.SaveTo(path) |
.SaveAsPng(path) / .SaveAsJpeg(path) / .SaveAsSvg(path) |
Lista kontrolna migracji
Użyj tych wzorców grep, aby znaleźć wszystkie wystąpienia BARCODE-ówInfragisticsw swoim kodzie źródłowym:
# Namespace references
grep -r "Infragistics.WinForms.Barcode\|Infragistics.Win.UltraWinBarcode" --include="*.cs" .
grep -r "Infragistics.Controls.Barcodes" --include="*.cs" .
grep -r "Infragistics.WPF.BarcodeReader" --include="*.csproj" .
# WinForms generation types
grep -r "UltraWinBarcode" --include="*.cs" .
grep -r "Symbology\.Code" --include="*.cs" .
grep -r "barcode\.SaveTo(" --include="*.cs" .
# WPF reading types and patterns
grep -r "new BarcodeReader()" --include="*.cs" .
grep -r "DecodeComplete" --include="*.cs" .
grep -r "ReaderDecodeArgs" --include="*.cs" .
grep -r "SymbologyType\." --include="*.cs" .
grep -r "e\.Value\|ReaderDecodeArgs" --include="*.cs" .
grep -r "BitmapImage" --include="*.cs" .
# TaskCompletionSource usage (likely barcode-related if near above patterns)
grep -r "TaskCompletionSource" --include="*.cs" .
# Namespace references
grep -r "Infragistics.WinForms.Barcode\|Infragistics.Win.UltraWinBarcode" --include="*.cs" .
grep -r "Infragistics.Controls.Barcodes" --include="*.cs" .
grep -r "Infragistics.WPF.BarcodeReader" --include="*.csproj" .
# WinForms generation types
grep -r "UltraWinBarcode" --include="*.cs" .
grep -r "Symbology\.Code" --include="*.cs" .
grep -r "barcode\.SaveTo(" --include="*.cs" .
# WPF reading types and patterns
grep -r "new BarcodeReader()" --include="*.cs" .
grep -r "DecodeComplete" --include="*.cs" .
grep -r "ReaderDecodeArgs" --include="*.cs" .
grep -r "SymbologyType\." --include="*.cs" .
grep -r "e\.Value\|ReaderDecodeArgs" --include="*.cs" .
grep -r "BitmapImage" --include="*.cs" .
# TaskCompletionSource usage (likely barcode-related if near above patterns)
grep -r "TaskCompletionSource" --include="*.cs" .
Przejrzyj wszystkie dopasowania:
- Zamiany
UltraWinBarcode: zamień naBarcodeWriter.CreateBarcode() - Bloki
new BarcodeReader()+DecodeComplete: zamień naBarcodeReader.Read() - Listy flag
SymbologyType: usuń całkowicie - Ładowania
BitmapImageużywane dla danych wejściowych z kodami kreskowymi: zamień na bezpośrednią ścieżkę/strumień/bajty - Ciało wywołań zwrotnych
ReaderDecodeArgs e: wyodrębnije.Value→result.Value,e.Symbology→result.Format IDisposablew klasach usług kodów kreskowych: usuń, jeśli jedynym zasobem do wyrzucenia było_reader
Porównanie funkcji
| Funkcja | InfragisticsBarCode | IronBarcode |
|---|---|---|
| Generowanie BarCode-ów w WinForms | Tak (UltraWinBarcode) | Tak |
| Odczytywanie BarCodes w WinForms | Niedostępne | Tak |
| Generowanie kodów kreskowych w WPF | Tak (XamBarcode) | Tak |
| Odczytywanie BarCode w WPF | Tak (sterowane zdarzeniami) | Tak (synchroniczne) |
| ASP.NET Core | Niedostępne | Tak |
| Konsola / Usługa robocza | Niedostępne | Tak |
| Docker / Linux | Niedostępne | Tak |
| Azure Functions | Niedostępne | Tak |
| Blazor Server | Niedostępne | Tak |
| Automatyczne wykrywanie formatowania | Nie — flagi typu SymbologyType są wymagane | Tak |
| Odczytywanie BarCodes z plików PDF | Niedostępne | Tak (język ojczysty) |
| Wielowątkowe odczyty | Nie | Tak |
| Odczyt partii (wbudowany) | Nie | Tak |
| Kontrola korekcji błędów QR | Niedostępne | Tak |
| Statyczne API (bez instancji) | Nie | Tak |
| Wymagana subskrypcja Suite pakietu | Tak (Infragistics Ultimate, 2399 złotych+/rok) | Nie |
| Licencja wieczysta | Nie | Tak — od 749 USD |
Kluczowe korzyści po migracji
Odczyt kodów kreskowych w WinForms. Jeśli migracja była zainicjowana przez wymaganie odczytu w WinForms, to jest główny ostateczny wynik: BarcodeReader.Read(imagePath) kompiluje się i działa w WinForms bez żadnej dodatkowej konfiguracji.
Obsługa .NET Core i konsoli. Interfejsy API sieci Web, usługi działające w tle oraz narzędzia konsolowe mogą teraz zarówno generować, jak i odczytywać kody kreskowe przy użyciu tego samego pakietu. Jeśli dotychczas korzystałeś z oddzielnych łańcuchów narzędzi lub rozwiązań zastępczych dla tych typów projektów, teraz nie są one już potrzebne.
Brak standardowych obsługi zdarzeń. Usunięto obsługę DecodeComplete, mostek TaskCompletionSource, ładowanie BitmapImage i czyszczenie Dispose(). Pozostaje logika BarCode'ów.
Brak specyfikacji symbologii. Formatki, które wcześniej cicho się nie powiodły z powodu brakujących flag SymbologyType, będą teraz poprawnie wykryte. Automatyczne wykrywanie obejmuje ponad 50 formatów bez konieczności konfiguracji.
Ta sama klasa usługowa we wszystkich typach projektów. Pojedynczy wrapper BarcodeService używający BarcodeReader.Read() i BarcodeWriter.CreateBarcode() może być współdzielony w WinForms, WPF,ASP.NET Corei w dowolnym innym projekcie w rozwiązaniu. Nie należy stosować implementacji specyficznych dla danego frameworka.
Nie jest wymagana subskrypcjaInfragisticsUltimate wyłącznie w celu korzystania z funkcji kodów kreskowych. Jeśli obsługa kodów kreskowych była jedynym powodem, dla którego w ramach projektu wykupiono subskrypcjęInfragisticsUltimate, lub jeśli był to istotny czynnik decyzyjny,IronBarcode jest samodzielnym pakietem z opcjami licencji wieczystej, których cena zaczyna się od 749 USD dla jednego programisty.
Sama migracja jest mechaniczna, gdy już zlokalizujesz wszystkie miejsca użycia kodów kreskowych Infragistics. Najbardziej złożoną częścią jest zamiana klasy usługi WPF, a nawet to redukuje się do usunięcia klasy oraz zastąpienia wywołań przez BarcodeReader.Read(). Migracja generacji polega na zmianie nazw właściwości/metod w stosunku jeden do jednego. W zamian otrzymujesz jeden, spójny interfejs API, który działa w każdym potrzebnym typie projektu.
Często Zadawane Pytania
Dlaczego warto przejść z Infragistics BarCode na IronBarcode?
Typowe powody to uproszczenie licencjonowania (eliminacja złożoności związanej z SDK i kluczem uruchomieniowym), zniesienie limitów przepustowości, uzyskanie natywnej obsługi plików PDF, usprawnienie wdrażania w środowisku Docker/CI/CD oraz ograniczenie powtarzalnego kodu API w kodzie produkcyjnym.
Jak zastąpić wywołania API Infragistics za pomocą IronBarcode?
Zastąp standardowe fragmenty kodu dotyczące tworzenia instancji i licencjonowania wyrażeniem IronBarCode.License.LicenseKey = "key". Zastąp wywołania czytnika wyrażeniem BarcodeReader.Read(path), a wywołania zapisu wyrażeniem BarcodeWriter.CreateBarcode(data, encoding). Metody statyczne nie wymagają zarządzania instancjami.
Jak bardzo zmienia się kod podczas migracji z Infragistics BarCode do IronBarcode?
Większość migracji skutkuje zmniejszeniem liczby linii kodu. Usuwane są standardowe fragmenty dotyczące licencji, konstruktory instancji oraz jawna konfiguracja formatów. Podstawowe operacje odczytu/zapisu są mapowane na krótsze odpowiedniki w IronBarcode z bardziej przejrzystymi obiektami wynikowymi.
Czy podczas migracji muszę mieć zainstalowane zarówno Infragistics BarCode, jak i IronBarcode?
Nie. Większość migracji polega na bezpośredniej wymianie, a nie na równoległym działaniu. Należy migrować po jednej klasie usługowej na raz, zastąpić odwołanie do NuGet oraz zaktualizować wzorce instancjonowania i wywoływania API przed przejściem do kolejnej klasy.
Jaka jest nazwa pakietu NuGet dla IronBarcode?
Pakiet nosi nazwę „IronBarcode” (z wielkimi literami B i C). Zainstaluj go za pomocą polecenia „Install-Package IronBarcode” lub „dotnet add package IronBarcode”. Dyrektywa using w kodzie to „using IronBarcode;”.
W jaki sposób IronBarcode upraszcza wdrażanie Docker w porównaniu z Infragistics BarCode?
IronBarcode to pakiet NuGet bez zewnętrznych plików SDK ani konfiguracji licencji. W Dockerze należy ustawić zmienną środowiskową IRONBARCODE_LICENSE_KEY, a pakiet zajmie się weryfikacją licencji podczas uruchamiania.
Czy IronBarcode automatycznie wykrywa wszystkie formaty kodów kreskowych po migracji z Infragistics?
Tak. IronBarcode automatycznie wykrywa symbole we wszystkich obsługiwanych formatach. Wyraźne wyliczenie typów kodów kreskowych nie jest wymagane. Jeśli format jest już znany, a wydajność ma znaczenie, BarcodeReaderOptions pozwala ograniczyć obszar wyszukiwania w celu optymalizacji.
Czy IronBarcode może odczytywać BarCodes z plików PDF bez oddzielnej biblioteki?
Tak. BarCodeReader.Read("document.pdf") przetwarza pliki PDF natywnie. Wyniki obejmują PageNumber, Format, Value i Confidence dla każdego znalezionego kodu kreskowego. Nie jest wymagany żaden zewnętrzny etap renderowania pliku PDF.
W jaki sposób IronBarcode obsługuje równoległe przetwarzanie kodów kreskowych?
Metody statyczne IronBarcode są bezstanowe i bezpieczne dla wątków. Użyj Parallel.ForEach bezpośrednio na listach plików bez zarządzania instancjami dla poszczególnych wątków. BarcodeReaderOptions.MaxParallelThreads kontroluje wewnętrzny limit wątków.
Jakie właściwości wyników ulegają zmianie podczas migracji z Infragistics BarCode do IronBarcode?
Typowe zmiany nazw: BarcodeValue staje się Value, BarcodeType staje się Format. Wyniki IronBarcode zawierają również Confidence i PageNumber. Funkcja wyszukiwania i zamiany w całym rozwiązaniu obsługuje zmiany nazw w istniejącym kodzie przetwarzania wyników.
Jak skonfigurować licencjonowanie IronBarcode w potoku CI/CD?
Zapisz IronBarcode_LICENSE_KEY jako sekret potoku i przypisz IronBarCode.License.LicenseKey w kodzie uruchamiającym aplikację. Jeden sekret obejmuje wszystkie środowiska, w tym środowisko programistyczne, testowe, przejściowe i produkcyjne.
Czy IronBarcode obsługuje generowanie kodów QR z niestandardowym stylem?
Tak. Funkcja QRCodeWriter.CreateQrCode() obsługuje niestandardowe kolory za pomocą ChangeBarCodeColor(), osadzanie logo za pomocą AddBrandLogo(), konfigurowalne poziomy korekcji błędów oraz wiele formatów wyjściowych, w tym PNG, JPG, PDF i strumień.

