Cómo Leer y Escanear Códigos de Barras en C# Usando NET MAUI
Migrating from Código de barras de Infragisticsto IronBarcode
La mayoría de las migraciones de códigos de barras de Infragisticsse producen porque el equipo necesitaba la lectura de códigos de barras en un proyecto donde solo estaba disponible la generación (WinForms, ASP.NET Coreo cualquier proyecto fuera de WPF) o porque la API de lectura de WPF basada en eventos resultó demasiado frágil para su uso en producción. El patrón de puente TaskCompletionSource, el campo compartido _result que hace que las llamadas concurrentes sean inseguras, y los fallos silenciosos debido a la falta de SymbologyType son todas razones comunes por las que los equipos buscan una alternativa.
Esta guía describe el proceso completo de migración: la eliminación de los paquetes de códigos de barras de Infragistics, la sustitución del código de generación y lectura tanto en contextos WinForms como WPF, y la adición de la funcionalidad de códigos de barras a los tipos de proyectos donde Infragisticsno ofrecía ningún tipo de soporte.
Inicio rápido
Paso 1: Retire los paquetes con código de barras de Infragistics
Elimina los paquetes NuGet de códigos de barras de Infragisticsde tu proyecto. Dependiendo de los objetivos que estuvieras utilizando:
# 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
Si el archivo de tu proyecto hace referencia a ambos, elimínalos. La licencia de InfragisticsUltimate no se ve afectada por la eliminación de paquetes específicos para códigos de barras si tiene otros componentes de Infragisticsen uso.
Paso 2: Instalar IronBarcode
dotnet add package IronBarcode
dotnet add package IronBarcode
IronBarcode es un paquete único que funciona en WinForms, WPF, ASP.NET Core, consola, Blazor Server, Docker, Azure Functionsy AWS Lambda. No necesitas paquetes separados para cada framework.
Paso 3: Actualizar los espacios de nombres
Reemplace los espacios de nombres de Infragisticsbarcode con IronBarCode (B mayúscula, C mayúscula):
// 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
Paso 4: Inicializar la licencia
Agregue la inicialización de la licencia una vez al iniciar la aplicación — Program.cs, App.xaml.cs, o su raíz de composición DI:
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY";
Imports IronBarCode
IronBarCode.License.LicenseKey = "YOUR-LICENSE-KEY"
Ejemplos de migración de código
Generación de WinForms: UltraWinBarcode a BarcodeWriter
El patrón de generación de WinForms se adapta fácilmente al BarcodeWriter de IronBarcode:
Antes (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)
Después (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)
El valor enum de InfragisticsSymbology se mueve al enum BarcodeEncoding, que es un parámetro de CreateBarcode() en lugar de una asignación de propiedad. Los datos se convierten en el primer argumento. SaveTo() se convierte en .SaveAsPng(), .SaveAsJpeg(), .SaveAsSvg(), o .SaveAsPdf() dependiendo de su formato de salida.
Si necesita cambiar el tamaño del código de barras antes de guardarlo:
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)
Lectura basada en eventos de WPF: De una clase de servicio a dos líneas
Esta es la reducción más significativa en la migración. El patrón de lectura de InfragisticsWPF requiere una clase de servicio completa:
Antes (Infragistics WPF — ~35 líneas):
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
Después (IronBarcode — 2 líneas):
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")
Toda la clase de servicio — gestión de instancias, conexión de eventos, TaskCompletionSource, carga de BitmapImage, Dispose() — desapareció. BarcodeReader.Read() es síncrono, estático y acepta directamente una cadena de ruta de archivo.
Si también estuvieras devolviendo el tipo de simbología:
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 reemplaza e.Value. result.Format reemplaza e.Symbology.
Agregar lectura a WinForms (anteriormente imposible)
Si estabas en un proyecto WinForms que solo tenía generación, ahora la lectura está disponible con el mismo paquete:
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
Sin paquetes adicionales, sin configuración específica del framework. La misma llamada BarcodeReader.Read() funciona en WinForms así como en WPF.
Punto final de ASP.NET Core(anteriormente imposible)
La generación y lectura de códigos de barras en un controlador ASP.NET Coreno era posible con los paquetes de Infragistics. Con 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() acepta un Stream directamente — no es necesario guardar la carga en disco primero.
Lectura de códigos de barras PDF
IronBarcode lee códigos de barras de documentos PDF de forma nativa, sin necesidad de ningún paquete adicional:
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 no tenía nada equivalente: la lectura de códigos de barras de PDF requería convertir las páginas PDF en imágenes externamente antes de escanearlas.
Procesamiento por lotes: de secuencial a paralelo
Antes (Infragistics: secuencial, no seguro para la concurrencia en la paralelización):
// 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()
Después (IronBarcode — paralelo, seguro para subprocesos):
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)
Eliminando el patrón de eliminación
Si su código tenía implementaciones de IDisposable alrededor de BarcodeReader de Infragistics, esas pueden eliminarse por completo. El BarcodeReader de IronBarcode es una clase estática. No hay instancia que crear, no hay manejador de eventos que desvincular y no hay Dispose() que llamar.
// 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)()
Un servicio de envoltura ligero para fines de inyección de dependencias es sencillo:
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
No hay inyección de constructor, no hay Dispose(), no hay gestión de eventos.
Problemas comunes de migración
Banderas de tipo simbología eliminadas
La propiedad SymbologyTypes en el lector WPF de Infragisticsrequería enumerar cada formato de barcode que querías soportar. IronBarcode no tiene equivalente: detecta automáticamente los más de 50 formatos compatibles en cada lectura.
Esto tiene un efecto secundario importante: si un formato de barcode en particular fallaba silenciosamente antes porque su bandera SymbologyType faltaba en la lista, IronBarcode ahora lo encontrará. Es posible que veas valores de códigos de barras en producción que antes se pasaban por alto silenciosamente. Este es el comportamiento correcto: esos códigos de barras siempre han estado ahí.
Si necesitas restringir los formatos devueltos (por razones de rendimiento o ambigüedad), BarcodeReaderOptions admite esto:
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)
No es necesario cargar la imagen de mapa de bits.
El lector WPF de Infragisticsrequería cargar imágenes como objetos BitmapSource a través de new BitmapImage(new Uri(path, UriKind.Absolute)). IronBarcode acepta directamente cadenas de rutas de archivo, matrices de bytes y flujos de datos:
// 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"))
Puedes eliminar cualquier importación de using System.Windows.Media.Imaging; que solo estuviera allí para la carga de imágenes relacionadas con barcode.
Patrón TaskCompletionSource eliminado
El campo TaskCompletionSource<string> que unía la respuesta impulsada por eventos DecodeComplete al código asíncrono ha desaparecido por completo. BarcodeReader.Read() es síncrono y devuelve sus resultados directamente.
Si tu código de llamada era await service.ReadBarcodeAsync(path), puedes simplificar a:
// 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";
Si desea preservar una interfaz asíncrona para las llamadas posteriores sin bloquear un hilo:
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
Cambios de nombre de la propiedad
| Infragistics | IronBarcode |
|---|---|
e.Value (en ReaderDecodeArgs) |
result.Value |
e.Symbology (en ReaderDecodeArgs) |
result.Format |
barcode.Data |
Primer argumento de BarcodeWriter.CreateBarcode() |
barcode.Symbology = Symbology.Code128 |
BarcodeEncoding.Code128 (parámetro) |
barcode.SaveTo(path) |
.SaveAsPng(path) / .SaveAsJpeg(path) / .SaveAsSvg(path) |
Lista de comprobación de la migración
Utilice estos patrones grep para encontrar todos los usos de códigos de barras de Infragisticsen su código fuente:
# 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" .
Analiza cada partido:
- Usos de
UltraWinBarcode: reemplazar conBarcodeWriter.CreateBarcode() - Bloques de
new BarcodeReader()+DecodeComplete: reemplazar conBarcodeReader.Read() - Listas de banderas
SymbologyType: eliminar completamente - Cargas
BitmapImageutilizadas para la entrada de barcode: reemplazar con ruta/flujo/bytes directos - Cuerpos de callbacks
ReaderDecodeArgs e: extraere.Value→result.Value,e.Symbology→result.Format IDisposableen clases de servicio de barcode: eliminar si el único recurso desechable era_reader
Comparación de características
| Característica | Código de barras de Infragistics | IronBarcode |
|---|---|---|
| Generación de códigos de barras con WinForms | Sí (UltraWinBarcode) | Sí |
| Lectura de códigos de barras en WinForms | No disponible | Sí |
| Generación de códigos de barras WPF | Sí (XamBarcode) | Sí |
| Lectura de códigos de barras en WPF | Sí (basado en eventos) | Sí (síncrono) |
| ASP.NET Core | No disponible | Sí |
| Consola / Servicio de trabajador | No disponible | Sí |
| Docker / Linux | No disponible | Sí |
| Azure Functions | No disponible | Sí |
| Servidor Blazor | No disponible | Sí |
| Detección de formato automático | No — Se requieren indicadores de SymbologyType | Sí |
| Lectura de códigos de barras PDF | No disponible | Sí (nativo) |
| Lecturas concurrentes seguras para subprocesos | No | Sí |
| Lectura por lotes (integrada) | No | Sí |
| Control de corrección de errores QR | No disponible | Sí |
| API estática (sin instancia) | No | Sí |
| Se requiere suscripción a la Suite | Sí (Infragistics Ultimate, $2,399+/año) | No |
| Licencia perpetua | No | Sí, desde $749 |
Principales ventajas tras la migración
Lectura de barcode en WinForms. Si la migración fue impulsada por un requisito de lectura de WinForms, este es el resultado principal: BarcodeReader.Read(imagePath) compila y se ejecuta en WinForms sin configuración adicional.
Compatibilidad con ASP.NET Corey la consola. Ahora, las API web, los servicios en segundo plano y las herramientas de consola pueden generar y leer códigos de barras utilizando el mismo paquete. Si utilizabas cadenas de herramientas o soluciones alternativas independientes para este tipo de proyectos, ya no existen.
Sin plantilla de manejador de eventos. El manejador DecodeComplete, el puente TaskCompletionSource, la carga BitmapImage y la limpieza Dispose() se eliminan. Lo que queda es la lógica del código de barras.
Sin especificación de simbología. Los formatos que fallaban silenciosamente debido a la falta de banderas SymbologyType ahora se detectarán correctamente. La detección automática cubre los más de 50 formatos sin necesidad de configuración.
Misma clase de servicio en todos los tipos de proyectos. Un solo envoltorio BarcodeService usando BarcodeReader.Read() y BarcodeWriter.CreateBarcode() puede compartirse en WinForms, WPF, ASP.NET Corey cualquier otro proyecto en la solución. No hay implementaciones específicas del framework.
No se requiere una suscripción a InfragisticsUltimate solo para la funcionalidad de códigos de barras. Si la compatibilidad con códigos de barras fue la única razón por la que su proyecto contaba con una suscripción a InfragisticsUltimate, o si fue un factor importante en la decisión, IronBarcode es un paquete independiente con opciones de licencia perpetua a partir de $749 para un solo desarrollador.
La migración en sí es un proceso mecánico una vez que se ha localizado el uso de todos los códigos de barras de Infragistics. La parte más compleja es la sustitución de la clase de servicio WPF, y aun eso se reduce a eliminar la clase y sustituir las llamadas por BarcodeReader.Read(). La migración de generación consiste en un cambio de nombre uno a uno de las propiedades/métodos. Lo que se obtiene a cambio es una API única y consistente que funciona en cualquier tipo de proyecto que se necesite.
Preguntas Frecuentes
¿Por qué debería migrar de Infragistics Barcode a IronBarcode?
Entre las razones más comunes se incluyen la simplificación de licencias (eliminando la complejidad de SDK + clave de tiempo de ejecución), la eliminación de límites de rendimiento, la obtención de compatibilidad nativa con PDF, la mejora de la implementación de Docker/CI/CD y la reducción de la repetición de API en el código de producción.
¿Cómo puedo sustituir las llamadas a la API de Infragistics por IronBarcode?
Sustituya la creación de instancias y la repetición de licencias por IronBarCode.License.LicenseKey = "key". Sustituya las llamadas al lector por BarcodeReader.Read(path) y las llamadas al escritor por BarcodeWriter.CreateBarcode(data, encoding). Los métodos estáticos no requieren gestión de instancias.
¿Cuánto cambia el código al migrar de Infragistics Barcode a IronBarcode?
La mayoría de las migraciones se traducen en menos líneas de código. Se eliminan la repetición de licencias, los constructores de instancias y la configuración explícita de formatos. Las operaciones básicas de lectura/escritura se traducen a equivalentes IronBarcode más cortos con objetos de resultado más limpios.
¿Necesito mantener instalados tanto Infragistics Barcode como IronBarcode durante la migración?
No. La mayoría de las migraciones son sustituciones directas en lugar de operaciones paralelas. Migre una clase de servicio cada vez, sustituya la referencia NuGet y actualice los patrones de instanciación y llamada a la API antes de pasar a la siguiente clase.
¿Cuál es el nombre del paquete NuGet para IronBarcode?
El paquete es 'IronBarCode' (con B y C mayúsculas). Instálalo con 'Install-Package IronBarCode' o 'dotnet add package IronBarCode'. La directiva using en el código es 'using IronBarCode;'.
¿Cómo simplifica IronBarcode el despliegue de Docker en comparación con Infragistics BarCode?
IronBarcode es un paquete NuGet sin archivos SDK externos ni configuración de licencia montada. En Docker, establezca la variable de entorno IRONBARCODE_LICENSE_KEY y el paquete se encargará de la validación de la licencia al inicio.
¿IronBarcode detecta automáticamente todos los formatos de código de barras tras la migración desde Infragistics?
Sí, IronBarcode detecta automáticamente la simbología de todos los formatos compatibles. No es necesaria la enumeración explícita de BarcodeTypes. Si ya se conoce el formato y el rendimiento es importante, BarcodeReaderOptions permite restringir el espacio de búsqueda como optimización.
¿Puede IronBarcode leer códigos de barras de PDF sin una biblioteca independiente?
Sí. BarcodeReader.Read("document.pdf") procesa archivos PDF de forma nativa. Los resultados incluyen PageNumber, Format, Value y Confidence para cada código de barras encontrado. No es necesario ningún paso externo de procesamiento de PDF.
¿Cómo gestiona IronBarcode el procesamiento paralelo de códigos de barras?
Los métodos estáticos de IronBarcode no tienen estado y son seguros para los hilos. Utilice Parallel.ForEach directamente sobre listas de archivos sin gestión de instancias por subproceso. BarcodeReaderOptions.MaxParallelThreads controla el presupuesto interno de hilos.
¿Qué propiedades de los resultados cambian al migrar de Infragistics Barcode a IronBarcode?
Cambios de nombre comunes: BarcodeValue se convierte en Value, BarcodeType se convierte en Format. Los resultados de IronBarcode también añaden Confidence y PageNumber. Una búsqueda y sustitución en toda la solución gestiona los cambios de nombre en el código de procesamiento de resultados existente.
¿Cómo configuro las licencias de IronBarcode en un proceso CI/CD?
Almacene IRONBARCODE_LICENSE_KEY como un secreto de canalización y asigne IronBarCode.License.LicenseKey en el código de inicio de la aplicación. Un secreto cubre todos los entornos, incluidos los de desarrollo, prueba, montaje y producción.
¿Admite IronBarcode la generación de códigos QR con estilos personalizados?
Sí. QRCodeWriter.CreateQrCode() admite colores personalizados mediante ChangeBarCodeColor(), incrustación de logotipos mediante AddBrandLogo(), niveles de corrección de errores configurables y múltiples formatos de salida, incluidos PNG, JPG, PDF y stream.

