Skip to footer content
MIGRATION GUIDES

Migrating from Scanbot SDK to IronBarcode

This guide is written for .NET development teams moving barcode processing from Scanbot SDK to IronBarcode for server-side, desktop, or expanded file-based scenarios. This is not a like-for-like replacement: Scanbot SDK is a mobile camera scanning component, and IronBarcode is a file and document processing library. The migration is a scope change driven by requirements that the camera-only model cannot satisfy. Teams replacing a live mobile camera scanning UI without adding other requirements should evaluate whether migration is appropriate before proceeding.

For teams who started with Scanbot for a MAUI mobile app and now need barcode processing in ASP.NET Core, a desktop build, or a document pipeline, the mechanical migration is straightforward. The core change is replacing ScanbotBarcodeSDK.BarcodeScanner.Open(configuration) with BarcodeReader.Read(source), where source is a file path, a stream, a byte array, or a PDF.

Why Migrate from Scanbot SDK

Server-Side Processing Requirements: Scanbot SDK does not compile in ASP.NET Core, console applications, Azure Functions, or any non-MAUI project. When the mobile application requires a server-side companion that also processes barcodes — extracting them from uploaded PDFs or validating barcode values in incoming documents — Scanbot cannot cross that boundary. IronBarcode runs in all of those contexts with the same BarcodeReader.Read() API.

Desktop MAUI Support: Scanbot's package targets net10.0-android and net10.0-ios. A MAUI project that adds net10.0-windows or net10.0-maccatalyst to its TargetFrameworks will fail to build the desktop targets because the Scanbot package provides no assemblies for those platforms. IronBarcode supports Windows and macOS MAUI alongside iOS and Android, which means the same package works in a multi-target MAUI project without platform-specific exclusions or conditional references.

PDF Document Workflows: There is no BarcodeScanner.Read(filePath) in Scanbot. When a workflow evolves to include reading barcodes from document uploads, scanned image archives, or PDF invoices, Scanbot's architecture cannot accommodate it. IronBarcode reads PDFs and images directly, with each result carrying the page number on which the barcode was found.

Pricing Model Predictability: Scanbot uses a yearly flat fee. For some organizations, the annual renewal is the trigger for evaluating alternatives — particularly when the project scope has grown to include server-side or desktop targets that fall outside Scanbot's coverage. IronBarcode is a one-time perpetual purchase, eliminating the annual renewal obligation.

The Fundamental Problem

Scanbot SDK requires a live camera feed. When requirements expand beyond mobile, there is no equivalent path through the existing dependency:

// Scanbot SDK: camera-only — no file or server equivalent exists
var configuration = new BarcodeScannerConfiguration
{
    BarcodeFormats = new[] { BarcodeFormat.Code128, BarcodeFormat.QrCode }
};

// This call requires iOS or Android hardware and a MAUI camera UI
// It cannot be redirected to a file path, stream, or server context
var result = await ScanbotBarcodeSDK.BarcodeScanner.Open(configuration);
// Scanbot SDK: camera-only — no file or server equivalent exists
var configuration = new BarcodeScannerConfiguration
{
    BarcodeFormats = new[] { BarcodeFormat.Code128, BarcodeFormat.QrCode }
};

// This call requires iOS or Android hardware and a MAUI camera UI
// It cannot be redirected to a file path, stream, or server context
var result = await ScanbotBarcodeSDK.BarcodeScanner.Open(configuration);
Imports System.Threading.Tasks

' Scanbot SDK: camera-only — no file or server equivalent exists
Dim configuration As New BarcodeScannerConfiguration With {
    .BarcodeFormats = {BarcodeFormat.Code128, BarcodeFormat.QrCode}
}

' This call requires iOS or Android hardware and a MAUI camera UI
' It cannot be redirected to a file path, stream, or server context
Dim result = Await ScanbotBarcodeSDK.BarcodeScanner.Open(configuration)
$vbLabelText   $csharpLabel

IronBarcode accepts the same source types — file, stream, byte array, or PDF — in any project context:

// IronBarcode: the same call works in MAUI, ASP.NET Core, console, WPF, Azure Functions
IronBarCode.License.LicenseKey = "YOUR-KEY";

// From a file — works on any platform
var results = BarcodeReader.Read("invoice.pdf");
foreach (var result in results)
    Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.BarcodeType})");
// IronBarcode: the same call works in MAUI, ASP.NET Core, console, WPF, Azure Functions
IronBarCode.License.LicenseKey = "YOUR-KEY";

// From a file — works on any platform
var results = BarcodeReader.Read("invoice.pdf");
foreach (var result in results)
    Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.BarcodeType})");
Imports IronBarCode

' IronBarcode: the same call works in MAUI, ASP.NET Core, console, WPF, Azure Functions
License.LicenseKey = "YOUR-KEY"

' From a file — works on any platform
Dim results = BarcodeReader.Read("invoice.pdf")
For Each result In results
    Console.WriteLine($"Page {result.PageNumber}: {result.Value} ({result.BarcodeType})")
Next
$vbLabelText   $csharpLabel

IronBarcode vs Scanbot SDK: Feature Comparison

Feature Scanbot SDK IronBarcode
Input from file path No Yes
Input from stream No Yes
Input from byte array No Yes
PDF barcode extraction No Yes
Live camera viewfinder Yes No (use MediaPicker)
Barcode generation No Yes
iOS MAUI Yes Yes
Android MAUI Yes Yes
Windows MAUI No Yes
macOS MAUI No Yes
ASP.NET Core No Yes
Console / Server No Yes
Azure / Lambda / Docker No Yes
.NET Framework 4.6.2+ No Yes
ML error correction No Yes
Damaged barcode recovery No Yes
Auto format detection Yes Yes
1D formats 20+ 30+
2D formats QR, DataMatrix, PDF417, Aztec QR, DataMatrix, PDF417, Aztec, MaxiCode
License model Yearly flat fee One-time perpetual
Published pricing Contact sales Yes ($999–$5,999)

Quick Start: Scanbot SDK to IronBarcode Migration

Step 1: Replace NuGet Package

Remove the Scanbot package:

dotnet remove package ScanbotBarcodeSDK.MAUI
dotnet remove package ScanbotBarcodeSDK.MAUI
SHELL

If the project uses conditional package references in the .csproj file, remove those entries as well:


<PackageReference Include="ScanbotBarcodeSDK.MAUI" Version="8.0.0" />

<PackageReference Include="ScanbotBarcodeSDK.MAUI" Version="8.0.0" />
XML

Install IronBarcode:

dotnet add package IronBarcode
dotnet add package IronBarcode
SHELL

IronBarcode is available on NuGet and supports .NET 6, 7, 8, 9, and .NET Framework 4.6.2+. For a MAUI multi-target project, a single dotnet add package works across all targets — no platform-conditional package references are needed.

Step 2: Update Namespaces

Replace Scanbot namespaces with the IronBarcode namespace:

// Remove
using ScanbotBarcodeSDK.MAUI;

// Add
using IronBarCode;
// Remove
using ScanbotBarcodeSDK.MAUI;

// Add
using IronBarCode;
Imports IronBarCode
$vbLabelText   $csharpLabel

Step 3: Initialize License

Remove the Scanbot initialization block and replace it with the IronBarcode license key. Add the license initialization at application startup in MauiProgram.cs, App.xaml.cs, or Program.cs depending on project type:

// Remove this
ScanbotSDK.Initialize(new ScanbotSDKConfiguration
{
    LicenseKey = "YOUR-SCANBOT-LICENSE-KEY",
    EnableLogging = false
});

// Add this — one line, placed once at startup
IronBarCode.License.LicenseKey = "YOUR-IRONBARCODE-KEY";
// Remove this
ScanbotSDK.Initialize(new ScanbotSDKConfiguration
{
    LicenseKey = "YOUR-SCANBOT-LICENSE-KEY",
    EnableLogging = false
});

// Add this — one line, placed once at startup
IronBarCode.License.LicenseKey = "YOUR-IRONBARCODE-KEY";
' Remove this
ScanbotSDK.Initialize(New ScanbotSDKConfiguration With {
    .LicenseKey = "YOUR-SCANBOT-LICENSE-KEY",
    .EnableLogging = False
})

' Add this — one line, placed once at startup
IronBarCode.License.LicenseKey = "YOUR-IRONBARCODE-KEY"
$vbLabelText   $csharpLabel

Code Migration Examples

MAUI Photo Capture

Scanbot's scanning call opens a full-screen camera UI and returns when the user scans a barcode or cancels. IronBarcode does not provide a camera UI; the replacement uses MAUI's MediaPicker to invoke the system camera, capture a photo, and pass the image bytes to BarcodeReader.Read().

Scanbot SDK Approach:

using ScanbotBarcodeSDK.MAUI;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var configuration = new BarcodeScannerConfiguration
    {
        BarcodeFormats = new[]
        {
            BarcodeFormat.Code128,
            BarcodeFormat.QrCode,
            BarcodeFormat.Ean13
        },
        FinderAspectRatio = new AspectRatio(1, 1),
        TopBarBackgroundColor = Colors.DarkBlue
    };

    var result = await ScanbotBarcodeSDK.BarcodeScanner.Open(configuration);

    if (result.Status == OperationResult.Ok)
    {
        foreach (var barcode in result.Barcodes)
            ResultLabel.Text = $"{barcode.Format}: {barcode.Text}";
    }
}
using ScanbotBarcodeSDK.MAUI;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var configuration = new BarcodeScannerConfiguration
    {
        BarcodeFormats = new[]
        {
            BarcodeFormat.Code128,
            BarcodeFormat.QrCode,
            BarcodeFormat.Ean13
        },
        FinderAspectRatio = new AspectRatio(1, 1),
        TopBarBackgroundColor = Colors.DarkBlue
    };

    var result = await ScanbotBarcodeSDK.BarcodeScanner.Open(configuration);

    if (result.Status == OperationResult.Ok)
    {
        foreach (var barcode in result.Barcodes)
            ResultLabel.Text = $"{barcode.Format}: {barcode.Text}";
    }
}
Imports ScanbotBarcodeSDK.MAUI

Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
    Dim configuration = New BarcodeScannerConfiguration With {
        .BarcodeFormats = New BarcodeFormat() {
            BarcodeFormat.Code128,
            BarcodeFormat.QrCode,
            BarcodeFormat.Ean13
        },
        .FinderAspectRatio = New AspectRatio(1, 1),
        .TopBarBackgroundColor = Colors.DarkBlue
    }

    Dim result = Await ScanbotBarcodeSDK.BarcodeScanner.Open(configuration)

    If result.Status = OperationResult.Ok Then
        For Each barcode In result.Barcodes
            ResultLabel.Text = $"{barcode.Format}: {barcode.Text}"
        Next
    End If
End Sub
$vbLabelText   $csharpLabel

IronBarcode Approach:

// NuGet: dotnet add package IronBarcode
using IronBarCode;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    var first = results.FirstOrDefault();
    ResultLabel.Text = first != null
        ? $"{first.BarcodeType}: {first.Value}"
        : "No barcode found";
}
// NuGet: dotnet add package IronBarcode
using IronBarCode;

private async void ScanButton_Clicked(object sender, EventArgs e)
{
    var photo = await MediaPicker.CapturePhotoAsync();
    if (photo == null) return;

    using var stream = await photo.OpenReadAsync();
    using var ms = new MemoryStream();
    await stream.CopyToAsync(ms);

    var results = BarcodeReader.Read(ms.ToArray());
    var first = results.FirstOrDefault();
    ResultLabel.Text = first != null
        ? $"{first.BarcodeType}: {first.Value}"
        : "No barcode found";
}
Imports IronBarCode
Imports System.IO
Imports System.Linq
Imports System.Threading.Tasks

Private Async Sub ScanButton_Clicked(sender As Object, e As EventArgs)
    Dim photo = Await MediaPicker.CapturePhotoAsync()
    If photo Is Nothing Then Return

    Using stream = Await photo.OpenReadAsync()
        Using ms As New MemoryStream()
            Await stream.CopyToAsync(ms)

            Dim results = BarcodeReader.Read(ms.ToArray())
            Dim first = results.FirstOrDefault()
            ResultLabel.Text = If(first IsNot Nothing, $"{first.BarcodeType}: {first.Value}", "No barcode found")
        End Using
    End Using
End Sub
$vbLabelText   $csharpLabel

The UX change is that the user sees the system camera screen rather than Scanbot's embedded viewfinder with a scan region overlay. For business applications — inventory, logistics, document workflows — the system camera is adequate. The .NET MAUI barcode scanner tutorial covers the full integration pattern for both iOS and Android targets, including permission handling.

Scan Options and Configuration

Scanbot's BarcodeScannerConfiguration controls which formats the scanner accepts and how the camera UI looks. IronBarcode's BarcodeReaderOptions controls how the image is analyzed — processing speed, multi-barcode detection, and similar parameters. The configuration concepts map to different concerns because the underlying operations are different.

Scanbot SDK Approach:

var configuration = new BarcodeScannerConfiguration
{
    BarcodeFormats = new[] { BarcodeFormat.Code128, BarcodeFormat.QrCode },
    FinderAspectRatio = new AspectRatio(1, 1),
    FlashEnabled = false,
    OrientationLockMode = OrientationLockMode.Portrait
};

var result = await ScanbotBarcodeSDK.BarcodeScanner.Open(configuration);

if (result.Status == OperationResult.Ok)
{
    foreach (var barcode in result.Barcodes)
        Console.WriteLine($"{barcode.Format}: {barcode.Text}");
}
var configuration = new BarcodeScannerConfiguration
{
    BarcodeFormats = new[] { BarcodeFormat.Code128, BarcodeFormat.QrCode },
    FinderAspectRatio = new AspectRatio(1, 1),
    FlashEnabled = false,
    OrientationLockMode = OrientationLockMode.Portrait
};

var result = await ScanbotBarcodeSDK.BarcodeScanner.Open(configuration);

if (result.Status == OperationResult.Ok)
{
    foreach (var barcode in result.Barcodes)
        Console.WriteLine($"{barcode.Format}: {barcode.Text}");
}
Imports System
Imports System.Collections.Generic
Imports System.Threading.Tasks

Dim configuration As New BarcodeScannerConfiguration With {
    .BarcodeFormats = New BarcodeFormat() {BarcodeFormat.Code128, BarcodeFormat.QrCode},
    .FinderAspectRatio = New AspectRatio(1, 1),
    .FlashEnabled = False,
    .OrientationLockMode = OrientationLockMode.Portrait
}

Dim result = Await ScanbotBarcodeSDK.BarcodeScanner.Open(configuration)

If result.Status = OperationResult.Ok Then
    For Each barcode In result.Barcodes
        Console.WriteLine($"{barcode.Format}: {barcode.Text}")
    Next
End If
$vbLabelText   $csharpLabel

IronBarcode Approach:

using IronBarCode;

// Format detection is automatic — BarcodeReaderOptions controls processing behavior
var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Balanced,
    ExpectMultipleBarcodes = false
};

// Combined with the MediaPicker capture pattern
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;

using var photoStream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await photoStream.CopyToAsync(ms);

var results = BarcodeReader.Read(ms.ToArray(), options);
foreach (var result in results)
    Console.WriteLine($"{result.BarcodeType}: {result.Value}");
using IronBarCode;

// Format detection is automatic — BarcodeReaderOptions controls processing behavior
var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Balanced,
    ExpectMultipleBarcodes = false
};

// Combined with the MediaPicker capture pattern
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;

using var photoStream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await photoStream.CopyToAsync(ms);

var results = BarcodeReader.Read(ms.ToArray(), options);
foreach (var result in results)
    Console.WriteLine($"{result.BarcodeType}: {result.Value}");
Imports IronBarCode
Imports System.IO

' Format detection is automatic — BarcodeReaderOptions controls processing behavior
Dim options As New BarcodeReaderOptions With {
    .Speed = ReadingSpeed.Balanced,
    .ExpectMultipleBarcodes = False
}

' Combined with the MediaPicker capture pattern
Dim photo = Await MediaPicker.CapturePhotoAsync()
If photo Is Nothing Then Return

Using photoStream = Await photo.OpenReadAsync()
    Using ms As New MemoryStream()
        Await photoStream.CopyToAsync(ms)

        Dim results = BarcodeReader.Read(ms.ToArray(), options)
        For Each result In results
            Console.WriteLine($"{result.BarcodeType}: {result.Value}")
        Next
    End Using
End Using
$vbLabelText   $csharpLabel

Format specification is not required — IronBarcode auto-detects all supported formats. The BarcodeReaderOptions parameters that correspond most directly to Scanbot configuration are Speed (controls processing thoroughness versus performance) and ExpectMultipleBarcodes (continues scanning after the first match).

Server-Side PDF Processing

This scenario has no Scanbot equivalent. With IronBarcode, the same package installed for the MAUI mobile app can extract barcodes from PDFs in a server-side ASP.NET Core endpoint, giving teams a single barcode dependency that works across both deployment contexts.

Scanbot SDK Approach:

// Scanbot SDK cannot be used here — the package does not compile
// in ASP.NET Core, Azure Functions, console apps, or any non-MAUI project.
// There is no server-side Scanbot equivalent for this endpoint.
// Scanbot SDK cannot be used here — the package does not compile
// in ASP.NET Core, Azure Functions, console apps, or any non-MAUI project.
// There is no server-side Scanbot equivalent for this endpoint.
' Scanbot SDK cannot be used here — the package does not compile
' in ASP.NET Core, Azure Functions, console apps, or any non-MAUI project.
' There is no server-side Scanbot equivalent for this endpoint.
$vbLabelText   $csharpLabel

IronBarcode Approach:

// NuGet: dotnet add package IronBarcode
// Works in ASP.NET Core, console apps, Azure Functions, Docker — the same package as MAUI
using IronBarCode;

[HttpPost("extract-barcodes")]
public async Task<IActionResult> ExtractBarcodes(IFormFile file)
{
    using var ms = new MemoryStream();
    await file.CopyToAsync(ms);

    // Reads all barcodes from all pages of the uploaded PDF
    var results = BarcodeReader.Read(ms.ToArray());
    var values = results.Select(r => new
    {
        r.Value,
        Format = r.Format.ToString(),
        r.PageNumber
    });

    return Ok(values);
}
// NuGet: dotnet add package IronBarcode
// Works in ASP.NET Core, console apps, Azure Functions, Docker — the same package as MAUI
using IronBarCode;

[HttpPost("extract-barcodes")]
public async Task<IActionResult> ExtractBarcodes(IFormFile file)
{
    using var ms = new MemoryStream();
    await file.CopyToAsync(ms);

    // Reads all barcodes from all pages of the uploaded PDF
    var results = BarcodeReader.Read(ms.ToArray());
    var values = results.Select(r => new
    {
        r.Value,
        Format = r.Format.ToString(),
        r.PageNumber
    });

    return Ok(values);
}
Imports IronBarCode
Imports Microsoft.AspNetCore.Mvc
Imports System.IO
Imports System.Threading.Tasks

<HttpPost("extract-barcodes")>
Public Async Function ExtractBarcodes(file As IFormFile) As Task(Of IActionResult)
    Using ms As New MemoryStream()
        Await file.CopyToAsync(ms)

        ' Reads all barcodes from all pages of the uploaded PDF
        Dim results = BarcodeReader.Read(ms.ToArray())
        Dim values = results.Select(Function(r) New With {
            .Value = r.Value,
            .Format = r.Format.ToString(),
            .PageNumber = r.PageNumber
        })

        Return Ok(values)
    End Using
End Function
$vbLabelText   $csharpLabel

IronBarcode handles multi-page PDFs natively — each result carries a PageNumber property indicating which page the barcode was found on. The PDF barcode extraction guide covers the full range of PDF reading options including page range selection and performance tuning for large document batches.

ASP.NET Core Background Processing

For batch workflows such as Azure Functions or Worker Services processing archived PDF documents, IronBarcode provides the same API used in the MAUI app and the ASP.NET Core controller.

Scanbot SDK Approach:

// Scanbot SDK does not support this deployment context.
// The package will not compile in Azure Functions or Worker Services.
// Scanbot SDK does not support this deployment context.
// The package will not compile in Azure Functions or Worker Services.
' Scanbot SDK does not support this deployment context.
' The package will not compile in Azure Functions or Worker Services.
$vbLabelText   $csharpLabel

IronBarcode Approach:

// NuGet: dotnet add package IronBarcode
using IronBarCode;

// Azure Function or Worker Service batch processing
public void ProcessInvoiceBatch(IEnumerable<string> filePaths)
{
    foreach (var filePath in filePaths)
    {
        var results = BarcodeReader.Read(filePath);
        foreach (var result in results)
            Console.WriteLine($"File: {filePath} | Page {result.PageNumber}: {result.Value} ({result.BarcodeType})");
    }
}
// NuGet: dotnet add package IronBarcode
using IronBarCode;

// Azure Function or Worker Service batch processing
public void ProcessInvoiceBatch(IEnumerable<string> filePaths)
{
    foreach (var filePath in filePaths)
    {
        var results = BarcodeReader.Read(filePath);
        foreach (var result in results)
            Console.WriteLine($"File: {filePath} | Page {result.PageNumber}: {result.Value} ({result.BarcodeType})");
    }
}
Imports IronBarCode

Public Sub ProcessInvoiceBatch(filePaths As IEnumerable(Of String))
    For Each filePath In filePaths
        Dim results = BarcodeReader.Read(filePath)
        For Each result In results
            Console.WriteLine($"File: {filePath} | Page {result.PageNumber}: {result.Value} ({result.BarcodeType})")
        Next
    Next
End Sub
$vbLabelText   $csharpLabel

Scanbot SDK API to IronBarcode Mapping Reference

Scanbot SDK IronBarcode
ScanbotSDK.Initialize(new ScanbotSDKConfiguration { LicenseKey = "..." }) IronBarCode.License.LicenseKey = "key"
new BarcodeScannerConfiguration() new BarcodeReaderOptions()
ScanbotBarcodeSDK.BarcodeScanner.Open(configuration) BarcodeReader.Read(path / stream / bytes)
result.Status == OperationResult.Ok results.Any() or results.FirstOrDefault() != null
result.Barcodes Return value of BarcodeReader.Read()
barcode.Format result.BarcodeType (IronBarCode.BarcodeEncoding)
barcode.Text result.Value
BarcodeFormat.Code128 BarcodeEncoding.Code128
BarcodeFormat.QrCode BarcodeEncoding.QRCode
BarcodeFormat.Ean13 BarcodeEncoding.EAN13
BarcodeScannerConfiguration.FinderAspectRatio No equivalent — image framing handled by MediaPicker
BarcodeScannerConfiguration.FlashEnabled No equivalent — use MediaPicker options
Camera-required input File path, stream, byte array, or PDF
iOS and Android MAUI only All .NET platforms and project types

Common Migration Issues and Solutions

Issue 1: No Live Viewfinder Equivalent

Scanbot SDK: Provides a real-time camera viewfinder embedded in the scanning experience, with a scan region overlay, haptic feedback, and continuous barcode detection in the live video feed.

Solution: Use MAUI's MediaPicker.CapturePhotoAsync() to open the system camera and capture a still image for processing:

var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;

using var stream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);

var results = BarcodeReader.Read(ms.ToArray());
var photo = await MediaPicker.CapturePhotoAsync();
if (photo == null) return;

using var stream = await photo.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);

var results = BarcodeReader.Read(ms.ToArray());
Imports System.IO

Dim photo = Await MediaPicker.CapturePhotoAsync()
If photo Is Nothing Then Return

Using stream = Await photo.OpenReadAsync()
    Using ms As New MemoryStream()
        Await stream.CopyToAsync(ms)

        Dim results = BarcodeReader.Read(ms.ToArray())
    End Using
End Using
$vbLabelText   $csharpLabel

For business applications, the system camera is adequate. For consumer apps where the live overlay is central to the user experience, evaluate whether this UX change is acceptable before committing to the migration.

Issue 2: Camera Permissions Differences

Scanbot SDK: The Scanbot package handled camera permission requests as part of its UI flow, so camera permissions were implicitly managed by the SDK initialization and scanner launch.

Solution: With MediaPicker, MAUI handles permissions through the standard mechanism. Verify that AndroidManifest.xml includes the camera permission declaration and that Info.plist includes the NSCameraUsageDescription key. These entries are typically present in scaffolded MAUI project templates. If the app was previously using only Scanbot for camera access, confirm these manifest entries are in place before testing:


<uses-permission android:name="android.permission.CAMERA" />

<key>NSCameraUsageDescription</key>
<string>This app uses the camera to scan barcodes.</string>

<uses-permission android:name="android.permission.CAMERA" />

<key>NSCameraUsageDescription</key>
<string>This app uses the camera to scan barcodes.</string>
XML

Issue 3: Windows Build Errors Cleared

Scanbot SDK: The ScanbotBarcodeSDK.MAUI package targets only net10.0-android and net10.0-ios, causing build failures when net10.0-windows is present in TargetFrameworks.

Solution: Removing the Scanbot package reference resolves the Windows build failure. IronBarcode resolves correctly across all MAUI targets with no platform-conditional configuration:

# Verify the build succeeds on all targets after removing Scanbot and adding IronBarcode
dotnet build -f net10.0-windows10.0.19041.0
dotnet build -f net10.0-ios
dotnet build -f net10.0-android
# Verify the build succeeds on all targets after removing Scanbot and adding IronBarcode
dotnet build -f net10.0-windows10.0.19041.0
dotnet build -f net10.0-ios
dotnet build -f net10.0-android
SHELL

Issue 4: Format Enum Namespace Change

Scanbot SDK: Uses BarcodeFormat enum values such as BarcodeFormat.Code128 from the ScanbotBarcodeSDK.MAUI namespace.

Solution: IronBarcode uses the BarcodeEncoding enum in the IronBarCode namespace. Update all format references and any code that stores, compares, or switches on format enum values:

// Before (Scanbot)
BarcodeFormat.Code128
BarcodeFormat.QrCode
BarcodeFormat.Ean13

// After (IronBarcode)
BarcodeEncoding.Code128
BarcodeEncoding.QRCode
BarcodeEncoding.EAN13
// Before (Scanbot)
BarcodeFormat.Code128
BarcodeFormat.QrCode
BarcodeFormat.Ean13

// After (IronBarcode)
BarcodeEncoding.Code128
BarcodeEncoding.QRCode
BarcodeEncoding.EAN13
' Before (Scanbot)
BarcodeFormat.Code128
BarcodeFormat.QrCode
BarcodeFormat.Ean13

' After (IronBarcode)
BarcodeEncoding.Code128
BarcodeEncoding.QRCode
BarcodeEncoding.EAN13
$vbLabelText   $csharpLabel

Note that IronBarcode auto-detects all supported formats by default — explicit format filtering through BarcodeReaderOptions is only needed for performance optimization when the expected format is known in advance.

Scanbot SDK Migration Checklist

Pre-Migration Tasks

Audit the codebase to identify all Scanbot SDK usage:

grep -rn "ScanbotSDK.Initialize" --include="*.cs" .
grep -rn "BarcodeScannerConfiguration" --include="*.cs" .
grep -rn "ScanbotBarcodeSDK.BarcodeScanner.Open" --include="*.cs" .
grep -rn "result\.Barcodes" --include="*.cs" .
grep -rn "barcode\.Format" --include="*.cs" .
grep -rn "barcode\.Text" --include="*.cs" .
grep -rn "OperationResult\.Ok" --include="*.cs" .
grep -rn "using ScanbotBarcodeSDK" --include="*.cs" .
grep -rn "BarcodeFormat\." --include="*.cs" .
grep -rn "ScanbotSDK.Initialize" --include="*.cs" .
grep -rn "BarcodeScannerConfiguration" --include="*.cs" .
grep -rn "ScanbotBarcodeSDK.BarcodeScanner.Open" --include="*.cs" .
grep -rn "result\.Barcodes" --include="*.cs" .
grep -rn "barcode\.Format" --include="*.cs" .
grep -rn "barcode\.Text" --include="*.cs" .
grep -rn "OperationResult\.Ok" --include="*.cs" .
grep -rn "using ScanbotBarcodeSDK" --include="*.cs" .
grep -rn "BarcodeFormat\." --include="*.cs" .
SHELL
  • Document all scanning call sites and note whether they are in shared code, platform-specific code, or UI event handlers
  • Identify whether any pages or flows rely on Scanbot's real-time viewfinder as a primary user interaction
  • Confirm that camera permission entries exist in AndroidManifest.xml and Info.plist
  • Review the .csproj for any conditional package references tied to Scanbot

Code Update Tasks

  1. Remove ScanbotBarcodeSDK.MAUI NuGet package
  2. Remove any conditional <PackageReference> entries for Scanbot from the .csproj
  3. Install IronBarcode NuGet package
  4. Replace using ScanbotBarcodeSDK.MAUI; with using IronBarCode; in all files
  5. Replace ScanbotSDK.Initialize(...) with IronBarCode.License.LicenseKey = "key" at application startup
  6. Replace ScanbotBarcodeSDK.BarcodeScanner.Open(configuration) with MediaPicker.CapturePhotoAsync() followed by stream copy and BarcodeReader.Read(bytes) in MAUI camera workflows
  7. Replace ScanbotBarcodeSDK.BarcodeScanner.Open(configuration) with BarcodeReader.Read(filePath) or BarcodeReader.Read(stream) in server-side and file processing contexts
  8. Replace result.Status == OperationResult.Ok checks with results.Any() or results.FirstOrDefault() != null
  9. Replace result.Barcodes collection references with the return value of BarcodeReader.Read()
  10. Replace barcode.Text property access with result.Value
  11. Replace BarcodeFormat.* enum values with BarcodeEncoding.* equivalents
  12. Replace new BarcodeScannerConfiguration() with new BarcodeReaderOptions() where processing options are needed

Post-Migration Testing

  • Verify the build succeeds on all MAUI target platforms, including Windows and macOS if present
  • Test the MediaPicker.CapturePhotoAsync() flow on a physical iOS device and a physical Android device
  • Confirm that barcode values decoded by IronBarcode match values previously decoded by Scanbot for the same physical barcodes
  • Test multi-page PDF extraction if the project includes document processing workflows
  • Verify that format detection covers all barcode types previously configured in BarcodeScannerConfiguration.BarcodeFormats
  • Confirm that server-side endpoints or background jobs produce correct results on the same document samples
  • Verify camera permission prompts appear correctly on first launch on iOS and Android

Key Benefits of Migrating to IronBarcode

Unified Package Across All Deployment Targets: IronBarcode installs once and runs in MAUI mobile, MAUI desktop, ASP.NET Core, Azure Functions, console applications, and Windows desktop applications. Teams no longer need separate barcode dependencies for different parts of the same system.

PDF and Document Processing: IronBarcode reads barcodes from PDF files natively, with each result carrying the page number on which it was found. Document workflows that were previously impossible within the Scanbot model become straightforward operations with BarcodeReader.Read("document.pdf").

Windows and macOS Desktop MAUI Support: Multi-target MAUI projects that include Windows or macOS build without errors after removing Scanbot. IronBarcode provides the same barcode reading API on all four MAUI targets, eliminating the platform-conditional dependency management that Scanbot required.

Perpetual License Ownership: The one-time purchase model eliminates annual renewal obligations. Once licensed, IronBarcode can be used indefinitely at the purchased tier without recurring fees. Teams whose project scope expanded beyond Scanbot's mobile coverage find that the perpetual model better aligns with long-term cost planning.

Barcode Generation: IronBarcode can produce barcodes in all supported formats as image files, streams, or embedded content. Projects that need both reading and generation no longer require a second library alongside Scanbot.

Machine Learning-Assisted Reading: IronBarcode applies machine learning-based error correction and damaged barcode recovery for difficult real-world images — low contrast, partial damage, poor print quality — that standard detection algorithms fail to decode. This capability is particularly relevant for document processing workflows where image quality is variable.

Please noteScanbot SDK is a registered trademark of its respective owner. This site is not affiliated with, endorsed by, or sponsored by Scanbot SDK. All product names, logos, and brands are property of their respective owners. Comparisons are for informational purposes only and reflect publicly available information at the time of writing.

Frequently Asked Questions

Why should I migrate from Scanbot SDK to IronBarcode?

Common reasons include simplifying licensing (removing SDK + runtime key complexity), eliminating throughput limits, gaining native PDF support, improving Docker/CI/CD deployment, and reducing API boilerplate in production code.

How do I replace Scanbot API calls with IronBarcode?

Replace instance creation and licensing boilerplate with IronBarCode.License.LicenseKey = "key". Replace reader calls with BarcodeReader.Read(path) and writer calls with BarcodeWriter.CreateBarcode(data, encoding). Static methods require no instance management.

How much code changes when migrating from Scanbot SDK to IronBarcode?

Most migrations result in fewer lines of code. Licensing boilerplate, instance constructors, and explicit format configuration are removed. Core read/write operations map to shorter IronBarcode equivalents with cleaner result objects.

Do I need to keep both Scanbot SDK and IronBarcode installed during migration?

No. Most migrations are direct replacements rather than parallel operation. Migrate one service class at a time, replace the NuGet reference, and update the instantiation and API call patterns before moving to the next class.

What is the NuGet package name for IronBarcode?

The package is 'IronBarCode' (with capital B and C). Install it with 'Install-Package IronBarCode' or 'dotnet add package IronBarCode'. The using directive in code is 'using IronBarCode;'.

How does IronBarcode simplify Docker deployment compared to Scanbot SDK?

IronBarcode is a NuGet package with no external SDK files or mounted license configuration. In Docker, set the IRONBARCODE_LICENSE_KEY environment variable and the package handles license validation at startup.

Does IronBarcode detect all barcode formats automatically after migrating from Scanbot?

Yes. IronBarcode auto-detects symbology across all supported formats. Explicit BarcodeTypes enumeration is not required. If format is already known and performance matters, BarcodeReaderOptions allows restricting the search space as an optimization.

Can IronBarcode read barcodes from PDFs without a separate library?

Yes. BarcodeReader.Read("document.pdf") processes PDF files natively. Results include PageNumber, Format, Value, and Confidence for each barcode found. No external PDF rendering step is required.

How does IronBarcode handle parallel barcode processing?

IronBarcode's static methods are stateless and thread-safe. Use Parallel.ForEach directly over file lists without per-thread instance management. BarcodeReaderOptions.MaxParallelThreads controls the internal thread budget.

What result properties change when migrating from Scanbot SDK to IronBarcode?

Common renames: BarcodeValue becomes Value, BarcodeType becomes Format. IronBarcode results also add Confidence and PageNumber. A solution-wide search-and-replace handles the renames in existing result-processing code.

How do I set up IronBarcode licensing in a CI/CD pipeline?

Store IRONBARCODE_LICENSE_KEY as a pipeline secret and assign IronBarCode.License.LicenseKey in application startup code. One secret covers all environments including development, test, staging, and production.

Does IronBarcode support QR code generation with custom styling?

Yes. QRCodeWriter.CreateQrCode() supports custom colors via ChangeBarCodeColor(), logo embedding via AddBrandLogo(), configurable error correction levels, and multiple output formats including PNG, JPG, PDF, and stream.

Jordi Bardia
Software Engineer
Jordi is most proficient in Python, C# and C++, when he isn’t leveraging his skills at Iron Software; he’s game programming. Sharing responsibilities for product testing, product development and research, Jordi adds immense value to continual product improvement. The varied experience keeps him challenged and engaged, and he ...
Read More

Iron Support Team

We're online 24 hours, 5 days a week.
Chat
Email
Call Me