エラーを処理し、C#でバーコード操作をデバッグする方法

This article was translated from English: Does it need improvement?
Translated
View the article in English

バーコード処理パイプラインは、エラーが発生しても何も通知されない場合があり、結果がゼロと表示されると"バーコードが存在しない"と誤解されることがよくあります。しかし、破損したファイル、パスワードで保護されたPDF、フォーマットの不一致などが原因となっている可能性があります。 適切なログ記録と構造化されたエラー処理を実装することで、これらの障害が明らかになり、実用的な診断情報が得られます。

IronBarcodeは、BarcodeResultプロパティを提供します。 これらのプロパティには、検出されたフォーマット、デコードされた値、ページ番号、およびデコードが成功した各箇所の座標が含まれます。

このハウツーでは、型付き例外をキャッチして解釈する方法、失敗した読み取りからの診断コンテキストを抽出する方法、構造化ロギングを有効にする方法、バッチ操作中の失敗を分離する方法を説明します。

クイックスタート: バーコードエラーの処理と診断の有効化

読み書き呼び出しを、IronBarcodeの型付き例外をターゲットにしたtry-catchブロックでラップし、静かな失敗の代わりに実行可能なエラーメッセージを表示します。

  1. IronBarcode をNuGetパッケージマネージャでインストール

    PM > Install-Package BarCode
  2. このコード スニペットをコピーして実行します。

    using IronBarCode;
    using IronBarCode.Exceptions;
    
    try
    {
        BarcodeResults results = BarcodeReader.Read("label.pdf");
        Console.WriteLine($"Found {results.Count} barcode(s)");
    }
    catch (IronBarCodeFileException ex)
    {
        Console.Error.WriteLine($"File error: {ex.Message}");
    }
  3. 実際の環境でテストするためにデプロイする

    今日プロジェクトで IronBarcode を使い始めましょう無料トライアル

    arrow pointer

IronBarcodeの例外を捕捉して解釈するにはどうすればよいですか?

IronBarcodeの例外を、最も具体的なものから最も一般的なものまで捕捉します。 ファイルエラー、PDFパスワードエラー、エンコードエラーなど、処理が必要な例外を最初に処理するcatchブロックを配置し、その後に基本型を配置します。 IronBarCode.Exceptions 名前空間は 11 種類の例外タイプを定義しており、それぞれが特定の障害モードに対応しています:

IronBarcode例外タイプ—原因と推奨修正
例外タイプトリガー推奨される修正
IronBarCodeFileExceptionファイルが破損しているか、ロックされているか、またはサポートされていない画像形式です。ファイルがサポートされている画像形式であり、ロックされていないことを検証します。また、ファイルが見つからない場合は、 FileNotFoundExceptionを別途キャッチします。
IronBarCodePdfPasswordExceptionPDFがパスワードで保護されているか暗号化されているパスワードをPdfBarcodeReaderOptionsを通じて提供するか、ファイルをスキップしてログを記録します
IronBarCodeEncodingExceptionバーコード生成中の一般的なエンコーディングエラー入力データが目的のBarcodeWriterEncoding制約と一致することを確認します
IronBarCodeContentTooLongEncodingException選択されたシンボロジーで文字数制限を超えるデータを切り詰めるか、より高容量のフォーマット(QR, DataMatrix)に切り替えます
IronBarCodeFormatOnlyAcceptsNumericValuesEncodingException数値のみのフォーマット(EAN, UPC)に非数値文字を渡す入力をサニタイズするか、英数字フォーマット(Code128, Code39)に切り替えます
IronBarCodeUnsupportedRendererEncodingException選択されたBarcodeEncodingはIronBarcodeで書き出せませんBarcodeEncodingの代わりにBarcodeWriterEncoding列挙型を使用します
IronBarCodeParsingExceptionパース中に構造化データ(GS1-128)が検証に失敗するパース前にCode128GS1Parser.IsValid()を使ってGS1構造を検証します
IronBarCodeNativeExceptionネイティブ相互運用層でのエラー(DLLが見つからない、プラットフォームの互換性)プラットフォーム固有のNuGetパッケージがインストールされていることを確認します(BarCode.Linux, BarCode.macOS)
IronBarCodeConfidenceThresholdException無効な信頼度しきい値引数がリーダーオプションに渡されているConfidenceThresholdが0.0から1.0の間であることを確認します
IronBarCodeUnsupportedException現在のコンテキストではサポートされていない操作変更履歴で、お使いのバージョンでの機能の利用可否を確認します
IronBarCodeException基本タイプ — 上記に一致しないすべてのIronBarcode固有のエラーをキャッチします完全な例外詳細をログに記録し、調査のためにエスカレーションします

when 句を含む例外フィルターを使用して、深いネスト構造を生成することなく、重複する例外タイプをルーティングしてください。 ファイルが見つからない場合、IronBarCodeFileException ではなく標準の System.IO.FileNotFoundException がスローされるため、このケース用に別の catch ブロックを含めてください:

入力

請求書番号をエンコードしたCode128バーコード(成功経路)と、欠落したPDFの内容を表す倉庫ラベルバーコード(失敗経路)。

スキャンされた請求書の入力として使用されるCode128バーコードエンコーディングINV-2024-7829
Code128 barcode representing the content of the missing warehouse-labels.pdf failure path input
:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/exception-hierarchy.cs
using IronBarCode;
using IronBarCode.Exceptions;

// Success path: valid file present on disk
string filePath = "scanned-invoice.png";
// Failure path: file does not exist → caught by FileNotFoundException below
// string filePath = "warehouse-labels.pdf";

try
{
    BarcodeResults results = BarcodeReader.Read(filePath);
    foreach (BarcodeResult result in results)
    {
        // Print the detected symbology and decoded value for each barcode found
        Console.WriteLine($"[{result.BarcodeType}] {result.Value}");
    }
}
catch (IronBarCodePdfPasswordException ex)
{
    // PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retrying
    Console.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}");
}
catch (IronBarCodeFileException ex)
{
    // File is present but corrupted, locked, or in an unsupported format
    Console.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}");
}
catch (FileNotFoundException ex)
{
    // Missing files throw FileNotFoundException, not IronBarCodeFileException
    Console.Error.WriteLine($"File not found: {filePath} — {ex.Message}");
}
catch (IronBarCodeNativeException ex) when (ex.Message.Contains("DLL"))
{
    // The when filter routes only missing-DLL errors here; other native exceptions
    // fall through to the IronBarCodeException block below
    Console.Error.WriteLine($"Missing native dependency: {ex.Message}");
}
catch (IronBarCodeException ex)
{
    // Base catch for any IronBarcode-specific error not matched by the blocks above
    Console.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}");
}
Imports IronBarCode
Imports IronBarCode.Exceptions

' Success path: valid file present on disk
Dim filePath As String = "scanned-invoice.png"
' Failure path: file does not exist → caught by FileNotFoundException below
' Dim filePath As String = "warehouse-labels.pdf"

Try
    Dim results As BarcodeResults = BarcodeReader.Read(filePath)
    For Each result As BarcodeResult In results
        ' Print the detected symbology and decoded value for each barcode found
        Console.WriteLine($"[{result.BarcodeType}] {result.Value}")
    Next
Catch ex As IronBarCodePdfPasswordException
    ' PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retrying
    Console.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}")
Catch ex As IronBarCodeFileException
    ' File is present but corrupted, locked, or in an unsupported format
    Console.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}")
Catch ex As FileNotFoundException
    ' Missing files throw FileNotFoundException, not IronBarCodeFileException
    Console.Error.WriteLine($"File not found: {filePath} — {ex.Message}")
Catch ex As IronBarCodeNativeException When ex.Message.Contains("DLL")
    ' The when filter routes only missing-DLL errors here; other native exceptions
    ' fall through to the IronBarCodeException block below
    Console.Error.WriteLine($"Missing native dependency: {ex.Message}")
Catch ex As IronBarCodeException
    ' Base catch for any IronBarcode-specific error not matched by the blocks above
    Console.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}")
End Try
$vbLabelText   $csharpLabel

出力

ご注意有効なファイルは、デコードされたバーコードの種類と値に解決されます。

コンソール出力:Code128デコード成功を示す:[Code128] INV-2024-7829

ファイルが見つからない場合、FileNotFoundExceptionが発生し、専用のcatchブロックによって処理されます。

コンソール出力には、見つからない warehouse-labels.pdf ファイルに対する FileNotFoundException が表示されています。

when (ex.Message.Contains("DLL")) 上の IronBarCodeNativeException フィルターは、他のネイティブ例外に影響を与えることなく、依存関係の欠如によるエラーを特定のハンドラーに転送します。 この方法は、プラットフォーム固有のパッケージが不足している可能性があるDocker環境において特に有効です。

IronSoftware.Exceptions.LicensingException は、ライセンスキーが無効であるか、存在しない場合に別途スローされます。 この例外は、個々の読み取りまたは書き込み呼び出しの前後ではなく、アプリケーションの起動時に捕捉してください。


読み取り失敗から診断の詳細を抽出するにはどうすればよいですか?

読み取り操作で結果がゼロ件返されることは例外ではありません。 空の BarcodeResults コレクションが生成されます。 診断コンテキストは、入力パラメータ、設定済みオプション、および返された部分的な結果を検査することによって取得されます。

BarcodeResult オブジェクトは、PageNumber、および Points(コーナー座標)など、事後分析に役立つプロパティを提供します。 結果が表示されているものの予期しない内容である場合は、まず BarcodeType を期待される形式と照らし合わせ、PageNumber を確認してください。

入力

請求書番号をエンコードしたCode128 BARCODE。ReadingSpeed.Detailedを使用して読み取り、確実なスキャンを実現します。

スキャンされた請求書の入力として使用されるCode128バーコードエンコーディングINV-2024-7829
:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/diagnostic-logging.cs
using IronBarCode;

string filePath = "scanned-invoice.png";

// Configure the reader to narrow the search to specific symbologies and use
// a thorough scan pass — narrows false positives and improves decode accuracy
var options = new BarcodeReaderOptions
{
    ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit scan to known formats
    Speed = ReadingSpeed.Detailed,      // slower but more thorough — use ExtremeDetail for damaged images
    ExpectMultipleBarcodes = true       // scan the full image rather than stopping at the first match
};

BarcodeResults results = BarcodeReader.Read(filePath, options);

// An empty result is not an exception — it means no barcode matched the configured options
if (results == null || results.Count == 0)
{
    // Log the configured options alongside the warning so the cause is immediately actionable
    Console.Error.WriteLine($"[WARN] No barcodes found in: {filePath}");
    Console.Error.WriteLine($"  ExpectedTypes: {options.ExpectBarcodeTypes}");
    Console.Error.WriteLine($"  Speed: {options.Speed}");
    Console.Error.WriteLine($"  Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes");
}
else
{
    foreach (BarcodeResult result in results)
    {
        // Points contains the four corner coordinates of the barcode in the image;
        // use the first corner as a representative position indicator
        string pos = result.Points.Length > 0 ? $"{result.Points[0].X:F0},{result.Points[0].Y:F0}" : "N/A";
        Console.WriteLine($"[{result.BarcodeType}] {result.Value} "
            + $"(Page: {result.PageNumber}, Position: {pos})");
    }
}
Imports IronBarCode

Dim filePath As String = "scanned-invoice.png"

' Configure the reader to narrow the search to specific symbologies and use
' a thorough scan pass — narrows false positives and improves decode accuracy
Dim options As New BarcodeReaderOptions With {
    .ExpectBarcodeTypes = BarcodeEncoding.Code128 Or BarcodeEncoding.QRCode, ' limit scan to known formats
    .Speed = ReadingSpeed.Detailed,      ' slower but more thorough — use ExtremeDetail for damaged images
    .ExpectMultipleBarcodes = True       ' scan the full image rather than stopping at the first match
}

Dim results As BarcodeResults = BarcodeReader.Read(filePath, options)

' An empty result is not an exception — it means no barcode matched the configured options
If results Is Nothing OrElse results.Count = 0 Then
    ' Log the configured options alongside the warning so the cause is immediately actionable
    Console.Error.WriteLine($"[WARN] No barcodes found in: {filePath}")
    Console.Error.WriteLine($"  ExpectedTypes: {options.ExpectBarcodeTypes}")
    Console.Error.WriteLine($"  Speed: {options.Speed}")
    Console.Error.WriteLine($"  Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes")
Else
    For Each result As BarcodeResult In results
        ' Points contains the four corner coordinates of the barcode in the image;
        ' use the first corner as a representative position indicator
        Dim pos As String = If(result.Points.Length > 0, $"{result.Points(0).X:F0},{result.Points(0).Y:F0}", "N/A")
        Console.WriteLine($"[{result.BarcodeType}] {result.Value} " &
                          $"(Page: {result.PageNumber}, Position: {pos})")
    Next
End If
$vbLabelText   $csharpLabel

出力

ExpectBarcodeTypesが画像内のBARCODEと一致すると、読み取り結果としてタイプ、値、ページ番号、および位置が返されます。

コンソール出力には、ページ番号と位置座標を含むCode128デコード成功の表示があります。

ExpectBarcodeTypes に実際のシンボルが含まれていない場合、読み取りは空の結果を返します。 [WARN] ブロックには、設定されたタイプ、読み取り速度、および推奨される次のアクションがログに記録されます。

コンソール出力には、[WARN] Code128イメージに対してExpectBarcodeTypesがCode39に設定されているため、バーコードが見つかりませんでしたと表示されます。

診断の過程で、2つの共通パターンが現れる。 ExpectBarcodeTypesの設定が狭い範囲で結果が空になる場合、BARCODEが異なるシンボロジーを使用していることを意味することがよくあります; BarcodeEncoding.All まで展開することで、これを確認できます。 予期しないデコード結果は、通常、画質の悪さを示しています。

画像フィルターを適用し、読み込み速度を遅くして再試行すると、これらの問題は解決することがよくあります。 また、RemoveFalsePositive オプションを切り替えることで、ノイズの多い背景からの不要な読み取りを排除することもできます。

バーコード操作の詳細ログを有効にするにはどうすればよいですか?

IronBarcodeは、IronSoftware.Loggerを通じて組み込みのロギングAPIを提供します。 読み取りおよび書き込みパイプラインからの内部診断出力を取得するには、バーコード操作を行う前にログモードとファイルパスを設定してください。

入力

詳細ログが有効になっている場合、読み取り対象としてCode128バーコードのTIFF画像が使用されます。

Code128バーコードエンコーディングPROB-SCAN-999は、ログ記録例の問題スキャン入力として使用されます。
:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/enable-logging.cs
using IronBarCode;

// Enable IronBarcode's built-in logging — set BEFORE any read/write calls
// LoggingModes.All writes both debug output and file-level diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log"; // path is relative to the working directory

// All subsequent operations will write internal processing steps to the log file:
// image pre-processing stages, format detection attempts, and native interop calls
var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Detailed,
    ExpectBarcodeTypes = BarcodeEncoding.All  // scan for every supported symbology
};

BarcodeResults results = BarcodeReader.Read("problem-scan.tiff", options);
Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.");
Imports IronBarCode

' Enable IronBarcode's built-in logging — set BEFORE any read/write calls
' LoggingModes.All writes both debug output and file-level diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All
IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log" ' path is relative to the working directory

' All subsequent operations will write internal processing steps to the log file:
' image pre-processing stages, format detection attempts, and native interop calls
Dim options As New BarcodeReaderOptions With {
    .Speed = ReadingSpeed.Detailed,
    .ExpectBarcodeTypes = BarcodeEncoding.All  ' scan for every supported symbology
}

Dim results As BarcodeResults = BarcodeReader.Read("problem-scan.tiff", options)
Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.")
$vbLabelText   $csharpLabel

LoggingModes.All は、デバッグ出力とファイルレベルのログの両方をキャプチャします。 ログファイルには、画像の前処理段階、フォーマット検出の試行、ネイティブ相互運用呼び出しなど、公開APIからは見えない内部処理手順が記録されます。

構造化ロギングフレームワーク(Serilog、NLog、Microsoft.Extensions.Logging)を使用する本番環境のパイプラインにおいて、IronBarcodeの操作をミドルウェア層でラップすることで、組み込みのログファイルに加えて構造化されたJSONエントリが追加されます。組み込みのロガーは、サポートへのエスカレーションに役立つプレーンテキスト形式の診断情報を書き込みます; 構造化されたラッパーは、オブザーバビリティスタックに対してクエリ可能なフィールドを提供する。

:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/structured-wrapper.cs
using IronBarCode;
using System.Diagnostics;

// Lightweight wrapper that adds structured JSON observability to every read call.
// Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.
BarcodeResults ReadWithDiagnostics(string filePath, BarcodeReaderOptions options)
{
    var sw = Stopwatch.StartNew(); // start timing before the read so setup overhead is included
    try
    {
        BarcodeResults results = BarcodeReader.Read(filePath, options);
        sw.Stop();
        // Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatch
        Console.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"ok\","
            + $"\"count\":{results.Count},\"elapsed_ms\":{sw.ElapsedMilliseconds}}}");
        return results;
    }
    catch (Exception ex)
    {
        sw.Stop();
        // Emit a structured error entry to stderr with exception type, message, and elapsed time
        Console.Error.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"error\","
            + $"\"exception\":\"{ex.GetType().Name}\",\"message\":\"{ex.Message}\","
            + $"\"elapsed_ms\":{sw.ElapsedMilliseconds}}}");
        throw; // rethrow so the caller's catch blocks still handle the exception normally
    }
}
Imports IronBarCode
Imports System.Diagnostics

' Lightweight wrapper that adds structured JSON observability to every read call.
' Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.
Function ReadWithDiagnostics(filePath As String, options As BarcodeReaderOptions) As BarcodeResults
    Dim sw As Stopwatch = Stopwatch.StartNew() ' start timing before the read so setup overhead is included
    Try
        Dim results As BarcodeResults = BarcodeReader.Read(filePath, options)
        sw.Stop()
        ' Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatch
        Console.WriteLine($"{{""file"":""{filePath}"",""status"":""ok"",""count"":{results.Count},""elapsed_ms"":{sw.ElapsedMilliseconds}}}")
        Return results
    Catch ex As Exception
        sw.Stop()
        ' Emit a structured error entry to stderr with exception type, message, and elapsed time
        Console.Error.WriteLine($"{{""file"":""{filePath}"",""status"":""error"",""exception"":""{ex.GetType().Name}"",""message"":""{ex.Message}"",""elapsed_ms"":{sw.ElapsedMilliseconds}}}")
        Throw ' rethrow so the caller's catch blocks still handle the exception normally
    End Try
End Function
$vbLabelText   $csharpLabel

構造化された出力は、ログ集約ツールと直接統合されます。 コンテナ化された環境において、Pipe stdout を Fluentd、Datadog、または CloudWatch に送信します。 経過時間フィールドは、パフォーマンスの低下がSLA違反となる前にそれを明らかにする。

出力

詳細なログ記録が有効になっている状態でバーコードの読み取りが成功したことを示すコンソール出力とログファイルのパス

バッチバーコード処理のデバッグ方法を教えてください

複数のファイルを処理するには、各読み込み処理を個別のtry-catchブロックで分離し、各ファイルの結果を記録し、集計サマリーを生成します。 パイプラインは最初のエラーで停止するのではなく、障害が発生しても処理を継続します。

入力

scans/ バッチディレクトリにある 5 つの Code128 BARCODE 画像のうち 4 つ。 5番目のファイル(scan-05-broken.png)には無効なバイトが含まれており、ファイル例外が発生します。

Code128 barcode encoding ITEM-SQ-001

バッチ1 — スキャン1

Code128 barcode encoding ITEM-SQ-002

バッチ1 — スキャン2

Code128 barcode encoding ITEM-SQ-003

バッチ1 — スキャン3

Code128 barcode encoding ITEM-SQ-004

バッチ1 — スキャン4

:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/batch-processing.cs
using IronBarCode;
using IronBarCode.Exceptions;
using System.Diagnostics;

// Enable built-in logging for the entire batch run so internal processing steps
// are captured in the log file alongside the per-file console output
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "batch-run.log";

// Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectories
string[] files = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly);

var options = new BarcodeReaderOptions
{
    Speed = ReadingSpeed.Balanced,                                    // balances throughput vs accuracy
    ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit to known formats
    ExpectMultipleBarcodes = true                                     // scan each file fully
};

// Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)
int successCount = 0;
int failCount = 0;
int emptyCount = 0;
var errors = new List<(string File, string Error)>(); // per-file error context for root cause analysis
var sw = Stopwatch.StartNew();

foreach (string file in files)
{
    try
    {
        BarcodeResults results = BarcodeReader.Read(file, options);

        // Empty result is not an exception — the file was read but contained no matching barcode
        if (results == null || results.Count == 0)
        {
            emptyCount++;
            errors.Add((file, "No barcodes detected")); // record so caller can adjust options
            continue;
        }

        foreach (BarcodeResult result in results)
        {
            Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}");
        }
        successCount++;
    }
    catch (IronBarCodePdfPasswordException)
    {
        // PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover
        failCount++;
        errors.Add((file, "Password-protected PDF"));
    }
    catch (IronBarCodeFileException ex)
    {
        // File is corrupted, locked, or in an unsupported image format
        failCount++;
        errors.Add((file, $"File error: {ex.Message}"));
    }
    catch (FileNotFoundException ex)
    {
        // File was in the directory listing but deleted before the read completed (race condition)
        failCount++;
        errors.Add((file, $"File not found: {ex.Message}"));
    }
    catch (IronBarCodeException ex)
    {
        // Catch-all for any other IronBarcode-specific errors not handled above
        failCount++;
        errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"));
    }
    catch (Exception ex)
    {
        // Unexpected non-IronBarcode error — log the full type for investigation
        failCount++;
        errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"));
    }
}

sw.Stop();

// Summary report — parse failCount > 0 in CI/CD to set a non-zero exit code
Console.WriteLine("\n--- Batch Summary ---");
Console.WriteLine($"Total files:    {files.Length}");
Console.WriteLine($"Success:        {successCount}");
Console.WriteLine($"Empty reads:    {emptyCount}");
Console.WriteLine($"Failures:       {failCount}");
Console.WriteLine($"Elapsed:        {sw.Elapsed.TotalSeconds:F1}s");

if (errors.Any())
{
    Console.WriteLine("\n--- Error Details ---");
    foreach (var (errorFile, errorMsg) in errors)
    {
        Console.Error.WriteLine($"  {Path.GetFileName(errorFile)}: {errorMsg}");
    }
}
Imports IronBarCode
Imports IronBarCode.Exceptions
Imports System.Diagnostics

' Enable built-in logging for the entire batch run so internal processing steps
' are captured in the log file alongside the per-file console output
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All
IronSoftware.Logger.LogFilePath = "batch-run.log"

' Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectories
Dim files As String() = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly)

Dim options As New BarcodeReaderOptions With {
    .Speed = ReadingSpeed.Balanced,                                    ' balances throughput vs accuracy
    .ExpectBarcodeTypes = BarcodeEncoding.Code128 Or BarcodeEncoding.QRCode, ' limit to known formats
    .ExpectMultipleBarcodes = True                                     ' scan each file fully
}

' Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)
Dim successCount As Integer = 0
Dim failCount As Integer = 0
Dim emptyCount As Integer = 0
Dim errors As New List(Of (File As String, Error As String))() ' per-file error context for root cause analysis
Dim sw As Stopwatch = Stopwatch.StartNew()

For Each file As String In files
    Try
        Dim results As BarcodeResults = BarcodeReader.Read(file, options)

        ' Empty result is not an exception — the file was read but contained no matching barcode
        If results Is Nothing OrElse results.Count = 0 Then
            emptyCount += 1
            errors.Add((file, "No barcodes detected")) ' record so caller can adjust options
            Continue For
        End If

        For Each result As BarcodeResult In results
            Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}")
        Next
        successCount += 1
    Catch ex As IronBarCodePdfPasswordException
        ' PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover
        failCount += 1
        errors.Add((file, "Password-protected PDF"))
    Catch ex As IronBarCodeFileException
        ' File is corrupted, locked, or in an unsupported image format
        failCount += 1
        errors.Add((file, $"File error: {ex.Message}"))
    Catch ex As FileNotFoundException
        ' File was in the directory listing but deleted before the read completed (race condition)
        failCount += 1
        errors.Add((file, $"File not found: {ex.Message}"))
    Catch ex As IronBarCodeException
        ' Catch-all for any other IronBarcode-specific errors not handled above
        failCount += 1
        errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"))
    Catch ex As Exception
        ' Unexpected non-IronBarcode error — log the full type for investigation
        failCount += 1
        errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"))
    End Try
Next

sw.Stop()

' Summary report — parse failCount > 0 in CI/CD to set a non-zero exit code
Console.WriteLine(vbCrLf & "--- Batch Summary ---")
Console.WriteLine($"Total files:    {files.Length}")
Console.WriteLine($"Success:        {successCount}")
Console.WriteLine($"Empty reads:    {emptyCount}")
Console.WriteLine($"Failures:       {failCount}")
Console.WriteLine($"Elapsed:        {sw.Elapsed.TotalSeconds:F1}s")

If errors.Any() Then
    Console.WriteLine(vbCrLf & "--- Error Details ---")
    For Each errorDetail In errors
        Console.Error.WriteLine($"  {Path.GetFileName(errorDetail.File)}: {errorDetail.Error}")
    Next
End If
$vbLabelText   $csharpLabel

出力

バッチの概要を示すコンソール出力:成功4件、失敗1件、破損ファイルのエラー詳細

実行中、コンソールにはデコードされたバーコードごとに1行が出力され、その後にファイル数、成功数、空の読み取り数、失敗数、経過時間を含む概要が表示されます。エラーは、対応するファイル名と失敗理由とともに一覧表示されます。

このプロセスでは、成功(バーコードが見つかり、デコードされた)、空(ファイルは読み取られたがバーコードが検出されなかった)、失敗(例外が発生した)の3つの結果カテゴリが区別されます。 この区別は重要です。なぜなら、空の読み取りとエラーには異なる対応が必要となるからです。 空の読み取りが発生する場合は、より広範なフォーマット設定が必要になる可能性があり、エラーが発生する場合は、ファイルの欠落、リソースのロック、ネイティブ依存関係の欠落など、インフラストラクチャの問題を示していることが多い。

エラーリストは、根本原因分析を支援するために、ファイルごとのコンテキストを保持します。 CI/CDパイプラインでは、この出力を解析して終了コードを設定(完全成功の場合は0、failCountが0より大きい場合は0以外)するか、エラーの詳細をアラートシステムに転送してください。

スループットを向上させるには、MaxParallelThreadsを調整することで、並列処理を有効にしてください。 並列反復処理を Parallel.ForEach で囲み、エラーリストにはスレッドセーフなコレクションを使用することで、ファイルごとの分離を維持してください。


さらなる読み物

パイプラインが本番稼働準備完了になったら、ライセンスオプションを確認してください

よくある質問

IronBarcodeを使用してバーコード操作におけるエラーをどのように処理できますか?

IronBarcodeは型付き例外と組み込みロギングを提供し、バーコード操作におけるエラーを効率的に管理および処理し、アプリケーションのスムーズな動作を確保します。

バーコード問題をデバッグするためにIronBarcodeが提供する機能は何ですか?

IronBarcodeは診断の抽出と生産準備ができたバッチエラー分離を含み、無関係なバーコードタイプを無視することによりバーコード読み取りまでをより迅速かつ正確に行います。

IronBarcodeがバーコード処理中にエラーを記録できますか?

はい、IronBarcodeには組み込みのロギング機能があり、開発者はバーコード処理中のエラーの詳細をキャプチャして記録し、デバッグを容易にします。

IronBarcodeにおける型付き例外とは何ですか?

IronBarcodeの型付き例外は、バーコード操作の問題に関する詳細な情報を提供する特有のエラータイプであり、開発者が問題を診断し修正することを容易にします。

IronBarcodeはバッチエラー分離でどのように支援しますか?

IronBarcodeは生産準備ができたバッチエラー分離を提供し、エラーハンドリングにおいて、エラーニュースのあるバーコード操作を成功したものから分離し、バッチ処理におけるエラーマネジメントを簡略化します。

IronBarcodeを使用してバーコード操作から診断を抽出する方法がありますか?

はい、IronBarcodeは診断抽出ツールを提供し、開発者がバーコード操作の詳細情報を収集し、トラブルシューティングとエラー解決を支援します。

IronBarcodeはバーコードの外観カスタマイズをサポートしていますか?

はい、IronBarcodeはカラー、サイズ、テキスト注釈を含むバーコードの外観に関する詳細なカスタマイズオプションを提供し、特定のデザイン要件に合わせて調整が可能です。

IronBarcodeはビジネスプロセスの効率向上にどのように役立ちますか?

IronBarcodeは迅速かつ正確なバーコード生成と読み取りを可能にし、手動データ入力エラーの減少、在庫および資産追跡の改善などにより、ビジネスプロセスの効率を向上させます。

プロジェクトにIronBarcodeを実装するために必要なプログラミングスキルは何ですか?

IronBarcodeをプロジェクトに実装するためには、C#プログラミングの基本的な知識があれば十分で、開発者をガイドするための簡単なメソッドと包括的なドキュメントが提供されています。

IronBarcodeは小規模プロジェクトと大規模エンタープライズアプリケーションの両方に適していますか?

IronBarcodeはスケーラブルかつ多用途に設計されており、小規模プロジェクトおよび強力なバーコードソリューションを必要とする大規模エンタープライズアプリケーションの両方に適しています。

カーティス・チャウ
テクニカルライター

Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。

開発以外にも、CurtisはIoT(Internet of Things)への強い関心を持ち、ハードウェアとソフトウェアの統合方法を模索しています。余暇には、ゲームをしたりDiscordボットを作成したりして、技術に対する愛情と創造性を組み合わせています。

準備はできましたか?
Nuget ダウンロード 2,240,258 | バージョン: 2026.5 just released
Still Scrolling Icon

まだスクロールしていますか?

すぐに証拠が欲しいですか? PM > Install-Package BarCode
サンプルを実行する 文字列が BarCode になるのを見る。