How to Create a Desktop Barcode Application (Scanner/Generator) with .NET MAUI
For a comprehensive software solution, it is not just about mobile accessibility. The ability to deploy natively on desktop operating systems, such as Windows and macOS, is just as critical. This cross-platform approach enables businesses to leverage the full power of workstations for high-volume tasks such as asset tracking and administration.
Without proper desktop support, workflows are interrupted or, worse, forced onto less capable devices. This is particularly important in inventory management, where office staff need to generate batches of codes or verify scans rapidly without leaving their desks.
IronBarcode delivers the necessary tools to implement these features, ensuring your .NET MAUI application performs reliably on any computer.
In this article, we'll explain how to integrate IronBarcode to build both a Desktop Barcode Scanner and a Desktop Barcode Generator.
How to Create a Desktop Barcode Application using .NET MAUI in C#
- Download the IronBarcode C# library to integrate with .NET MAUI (Desktop Platform Framework)
- Read the uploaded barcode provided by the user with
Read - Display the barcode value to the .NET MAUI UI
- Generate a barcode with a string value with
CreateBarcode - Display the generated barcode in the .NET MAUI UI and save it as an image
.NET MAUI Desktop Application
Integrating IronBarcode into a .NET MAUI app is straightforward, as the library works natively with the desktop platform out of the box. In this example, we'll create both a barcode scanner and a barcode generator using IronBarcode separately.
Let's start with the barcode scanner first.
Barcode Scanner Interface XAML
For the .NET MAUI interface, a simple interface is implemented to allow users to upload barcode images via a submit button. The MainPage.xaml file within the project should be replaced with the contents shown below.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage"
BackgroundColor="{DynamicResource PageBackgroundColor}">
<ScrollView>
<VerticalStackLayout Spacing="25" Padding="30" VerticalOptions="Center">
<Label Text="Desktop Barcode Scanner"
FontSize="32"
HorizontalOptions="Center" />
<Image x:Name="ScannerImage"
HeightRequest="300"
WidthRequest="400"
BackgroundColor="#F0F0F0"
Aspect="AspectFit"
HorizontalOptions="Center" />
<Button Text="Select Image to Scan"
Clicked="OnScanButtonClicked"
HorizontalOptions="Center"
WidthRequest="200"/>
<Label x:Name="ResultLabel"
Text="Result will appear here..."
FontSize="20"
HorizontalOptions="Center"
HorizontalTextAlignment="Center" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Desktop Barcode Scanner Logic CS
Next, the logic for when the user clicks on the button is implemented. An OnScanButtonClicked event handler is attached to the scan button in the UI.
PickPhotoAsync is first used to let users choose the barcode to upload, followed by OpenReadAsync to access the file stream. The image data is immediately copied into a MemoryStream using CopyToAsync. This allows the data to be used simultaneously to display the image on screen and for the Read method to scan the barcode.
Finally, the barcode value is displayed in the UI if a valid barcode is detected, or a red message is displayed stating that no barcode was found in the image.
using IronBarCode;
namespace MauiApp1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
// Your license key is set here
IronBarCode.License.LicenseKey = "YOUR_KEY";
}
private async void OnScanButtonClicked(object sender, EventArgs e)
{
try
{
var fileResult = await MediaPicker.Default.PickPhotoAsync();
if (fileResult != null)
{
// 1. Copy the file content into a byte array or MemoryStream immediately
// This ensures we have the data in memory before the file closes
byte[] imageBytes;
using (var stream = await fileResult.OpenReadAsync())
using (var memoryStream = new MemoryStream())
{
await stream.CopyToAsync(memoryStream);
imageBytes = memoryStream.ToArray();
}
// 2. Set the Image Source for the UI
// We give the UI a FRESH stream from the bytes we just saved
ScannerImage.Source = ImageSource.FromStream(() => new MemoryStream(imageBytes));
// 3. Process the Barcode
// We give IronBarcode its OWN fresh stream from the same bytes
using (var processingStream = new MemoryStream(imageBytes))
{
// 4. Read the barcode with Read
var results = BarcodeReader.Read(processingStream);
// 5. Display barcode results
if (results != null && results.Count > 0)
{
// Successfully found barcode value
ResultLabel.Text = $"Success: {results[0].Value}";
ResultLabel.TextColor = Colors.Green;
}
else
{
// Image uploaded has no barcode or barcode value is not found
ResultLabel.Text = "No barcode detected.";
ResultLabel.TextColor = Colors.Red;
}
}
}
}
catch (Exception ex)
{
// Display any exception thrown in runtime
ResultLabel.Text = $"Error: {ex.Message}";
ResultLabel.TextColor = Colors.Red;
}
}
}
}
Output with Barcode Value found

As you can see, the application displays the barcode result and the uploaded barcode image.
Output with no Barcode Value found

As you can see, when a user uploads an image that doesn't contain a barcode, it displays a red message stating "No barcodes found."
Desktop Barcode Generator
The next part builds on the same concept by integrating IronBarcode into MAUI to create a barcode generator.
Barcode Generator Interface XAML
For the generator's interface, a simple form is implemented to allow text entry and barcode type selection via a dropdown menu. A button is included to trigger the generation and saving process, along with an image view to display the result. The MainPage.xaml file should be replaced with the contents shown below.
Please refer here for the complete list of 1D barcodes and here for 2D barcodes.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage"
BackgroundColor="{DynamicResource PageBackgroundColor}">
<ScrollView>
<VerticalStackLayout Spacing="20" Padding="30" VerticalOptions="Center">
<Label Text="Barcode Generator"
FontSize="32"
HorizontalOptions="Center" />
<Entry x:Name="BarcodeEntry"
Placeholder="Enter value (e.g. 12345 or https://ironsoftware.com)"
WidthRequest="300" />
<Picker x:Name="BarcodeTypePicker"
Title="Select Barcode Type"
WidthRequest="300">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>QRCode</x:String>
<x:String>Code128</x:String>
<x:String>EAN13</x:String>
<x:String>Code39</x:String>
<x:String>PDF417</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>
<Button Text="Generate & Save"
Clicked="OnGenerateButtonClicked"
HorizontalOptions="Center"
WidthRequest="200" />
<Image x:Name="GeneratedImage"
HeightRequest="200"
WidthRequest="300"
BackgroundColor="#F0F0F0"
Aspect="AspectFit" />
<Label x:Name="StatusLabel"
FontSize="16"
HorizontalOptions="Center"
HorizontalTextAlignment="Center" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
Desktop Barcode Generator Logic CS
Next, the logic for the button click event is implemented. An OnGenerateButtonClicked event handler is attached to the generate button in the UI.
User input is validated to ensure text is present and a type is selected, after which the selection is mapped to the correct BarcodeEncoding. BarcodeWriter.CreateBarcode is used to generate the image, resize it, and convert it to JPEG binary data. The image is then displayed on screen using a MemoryStream.
Finally, the generated barcode file is saved directly to the user's Desktop using File.WriteAllBytes, and the status label is updated to confirm the save location.
using IronBarCode;
using System.IO; // Required for saving files
namespace MauiApp1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
IronBarCode.License.LicenseKey = "YOUR-KEY";
// Set default selection
BarcodeTypePicker.SelectedIndex = 0;
}
private void OnGenerateButtonClicked(object sender, EventArgs e)
{
try
{
// 1. Get and Validate Input
string text = BarcodeEntry.Text;
if (string.IsNullOrWhiteSpace(text))
{
StatusLabel.Text = "Error: Please enter text.";
StatusLabel.TextColor = Colors.Red;
return;
}
if (BarcodeTypePicker.SelectedIndex == -1)
{
StatusLabel.Text = "Error: Please select a type.";
StatusLabel.TextColor = Colors.Red;
return;
}
// 2. Determine Encoding Type
string selectedType = BarcodeTypePicker.SelectedItem.ToString();
BarcodeEncoding encoding = BarcodeEncoding.QRCode;
switch (selectedType)
{
case "QRCode": encoding = BarcodeEncoding.QRCode; break;
case "Code128": encoding = BarcodeEncoding.Code128; break;
case "EAN13": encoding = BarcodeEncoding.EAN13; break;
case "Code39": encoding = BarcodeEncoding.Code39; break;
case "PDF417": encoding = BarcodeEncoding.PDF417; break;
}
// 3. Generate Barcode
var barcode = BarcodeWriter.CreateBarcode(text, encoding);
barcode.ResizeTo(400, 200); // Optional resizing
// 4. Convert to Bytes (JPEG)
var bytes = barcode.ToJpegBinaryData();
// 5. Update UI
GeneratedImage.Source = ImageSource.FromStream(() => new MemoryStream(bytes));
// 6. Save to Desktop automatically
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string fileName = $"barcode_{DateTime.Now:yyyyMMdd_HHmmss}.jpg";
string fullPath = Path.Combine(desktopPath, fileName);
File.WriteAllBytes(fullPath, bytes);
// 7. Show Success Message
StatusLabel.Text = $"Saved to Desktop:\n{fileName}";
StatusLabel.TextColor = Colors.Green;
}
catch (Exception ex)
{
StatusLabel.Text = $"Error: {ex.Message}";
StatusLabel.TextColor = Colors.Red;
}
}
}
}Imports IronBarCode
Imports System.IO ' Required for saving files
Namespace MauiApp1
Public Partial Class MainPage
Inherits ContentPage
Public Sub New()
InitializeComponent()
IronBarCode.License.LicenseKey = "YOUR-KEY"
' Set default selection
BarcodeTypePicker.SelectedIndex = 0
End Sub
Private Sub OnGenerateButtonClicked(sender As Object, e As EventArgs)
Try
' 1. Get and Validate Input
Dim text As String = BarcodeEntry.Text
If String.IsNullOrWhiteSpace(text) Then
StatusLabel.Text = "Error: Please enter text."
StatusLabel.TextColor = Colors.Red
Return
End If
If BarcodeTypePicker.SelectedIndex = -1 Then
StatusLabel.Text = "Error: Please select a type."
StatusLabel.TextColor = Colors.Red
Return
End If
' 2. Determine Encoding Type
Dim selectedType As String = BarcodeTypePicker.SelectedItem.ToString()
Dim encoding As BarcodeEncoding = BarcodeEncoding.QRCode
Select Case selectedType
Case "QRCode"
encoding = BarcodeEncoding.QRCode
Case "Code128"
encoding = BarcodeEncoding.Code128
Case "EAN13"
encoding = BarcodeEncoding.EAN13
Case "Code39"
encoding = BarcodeEncoding.Code39
Case "PDF417"
encoding = BarcodeEncoding.PDF417
End Select
' 3. Generate Barcode
Dim barcode = BarcodeWriter.CreateBarcode(text, encoding)
barcode.ResizeTo(400, 200) ' Optional resizing
' 4. Convert to Bytes (JPEG)
Dim bytes = barcode.ToJpegBinaryData()
' 5. Update UI
GeneratedImage.Source = ImageSource.FromStream(Function() New MemoryStream(bytes))
' 6. Save to Desktop automatically
Dim desktopPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim fileName As String = $"barcode_{DateTime.Now:yyyyMMdd_HHmmss}.jpg"
Dim fullPath As String = Path.Combine(desktopPath, fileName)
File.WriteAllBytes(fullPath, bytes)
' 7. Show Success Message
StatusLabel.Text = $"Saved to Desktop:{Environment.NewLine}{fileName}"
StatusLabel.TextColor = Colors.Green
Catch ex As Exception
StatusLabel.Text = $"Error: {ex.Message}"
StatusLabel.TextColor = Colors.Red
End Try
End Sub
End Class
End NamespaceOutput with Generated Barcode

As you can see, the application displays the generated barcode and saves it to the user's desktop.
Output Failure

Certain barcode types have restrictions and format requirements for the input value. When the barcode fails to generate, the application displays the IronBarcode exception, as shown above. Please refer to the respective detailed 1D and 2D for formatting for each barcode type.
To test the examples above (Desktop Barcode Scanner and the Desktop Barcode Generator), please download this sample project.
Frequently Asked Questions
What is the purpose of integrating IronBarcode into a .NET MAUI desktop application?
Integrating IronBarcode into a .NET MAUI application enables developers to build a cross-platform barcode scanner and generator solution that can operate directly on desktop environments like Windows and macOS, enhancing workflows such as inventory management and asset tracking.
How do you implement a desktop barcode scanner in .NET MAUI using IronBarcode?
To implement a barcode scanner, use IronBarcode’s `Read` method to scan a user-uploaded barcode image and display the results in the .NET MAUI UI. This involves handling user input, processing barcode data, and updating the interface with scan results.
How can a desktop barcode generator be created using IronBarcode?
A desktop barcode generator can be created using IronBarcode in .NET MAUI by providing a UI for text input and barcode type selection. Then, use `BarcodeWriter.CreateBarcode` to generate the barcode image, display it, and save it to the user’s desktop.
What file types are supported for saving barcode images in the IronBarcode generator?
IronBarcode supports saving barcode images in multiple formats, including JPEG. The example implementation saves the generated barcode image as a JPEG file.
Can IronBarcode handle different types of barcodes in a desktop application?
Yes, IronBarcode can handle various barcode types such as QRCode, Code128, EAN13, Code39, and PDF417, allowing for flexibility in creating and reading different barcode formats within a desktop application.
What is the role of `OnScanButtonClicked` in the barcode scanner logic?
`OnScanButtonClicked` is an event handler that triggers when the user clicks the scan button. It manages the process of picking, reading, and displaying the barcode image using IronBarcode in the .NET MAUI UI.
Why is cross-platform functionality important for desktop barcode applications?
Cross-platform functionality ensures that the barcode application can run natively on various desktop operating systems, such as Windows and macOS, enabling businesses to use powerful workstations for managing tasks like asset tracking and inventory management.
How does IronBarcode improve workflow efficiency in the context of barcode applications?
By allowing barcode generation and scanning directly on desktop environments, IronBarcode improves workflow efficiency by reducing the need to rely on mobile devices, thus minimizing interruptions and increasing the speed of tasks such as batch code generation and scan verification within office settings.

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.