OcrInternalsのx86アプリケーションでの展開エラー

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

IronTesseract.ReadScreenShot() は、IronOCRのAdvancedScanパイプラインを通ります。これはWindows x64プロセスでのみサポートされています。 x86アプリケーションから呼び出すと、OcrInternals 展開エラーで失敗します。たとえIronOcr.Extensions.AdvancedScan パッケージがインストールされていても。

Error while reading a screenshot, Error while deploying OcrInternals for IronOcr:
'Unable to locate 'OcrInternals' in
...\bin\Debug\runtimes\win-x86\native,
...\bin\Debug\runtimes\win.6.2-x86\native,
...\bin\Debug\runtimes\win.6-x86\native,
...\bin\Debug\,
...
nor in an embedded resource.'
Please install the NuGet Package 'IronOcr.Extension.AdvancedScan' when using IronOcr on Windows.
[Issue Code IRONOCR-OCRINTERNALS-DEPLOYMENT-ERROR-WIN]

失敗はReadScreenShot() 呼び出し自体で表面化します。

var ocr = new IronOcr.IronTesseract();
using (var input = new IronOcr.OcrInput())
{
    input.LoadImage("Step_1-5.jpg");
    var result = ocr.ReadScreenShot(input);
    Console.WriteLine(result.Text);
}
var ocr = new IronOcr.IronTesseract();
using (var input = new IronOcr.OcrInput())
{
    input.LoadImage("Step_1-5.jpg");
    var result = ocr.ReadScreenShot(input);
    Console.WriteLine(result.Text);
}
Imports IronOcr

Dim ocr As New IronTesseract()
Using input As New OcrInput()
    input.LoadImage("Step_1-5.jpg")
    Dim result = ocr.ReadScreenShot(input)
    Console.WriteLine(result.Text)
End Using
$vbLabelText   $csharpLabel

ReadScreenShot() が依存しているAdvancedScanのネイティブコンポーネントは、x86プロセス内ではサポートされていません。 IronOcr.Extensions.AdvancedScan のインストールが必要ですが、ホストプロセスのビット数を変更しないため、呼び出しは依然としてx86で実行できません。

注意AdvancedScanのインストールは、ReadScreenShot()をx86プロセスで動作させるものではありません。 それを呼び出すプロセスは必ずx64で実行される必要があります。)]}

解決策

オプション1: 直接x64をターゲット

最も簡潔な修正は、プロジェクトのプラットフォームターゲットをx64に切り替えることです。Visual Studioで:

  1. プロジェクトを右クリックし、プロパティを選択します。
  2. ビルドタブを開きます。
  3. プラットフォームターゲットx64に設定します。
  4. 32ビット優先をオフにします。
  5. 再ビルドして実行します。

ホストプロセスがx64として実行されていると、ReadScreenShot() はサポートされている環境で実行されます。

オプション2: アプリをx86のままにしてx64のヘルパープロセスを呼び出す

メインアプリケーションをx86のままにする必要がある場合、OCR操作を小さなx64のヘルパープロセスに移動し、既存のアプリから呼び出します。この構造は次のようになります:

MainWinForms.x86
  - .NET Framework Windows Forms app
  - Platform target: x86
  - Does not run ReadScreenShot() directly
  - Calls the x64 helper process
OcrHelper.x64
  - .NET Framework Console app
  - Platform target: x64
  - References IronOCR
  - References IronOcr.Extensions.AdvancedScan
  - Runs Ocr.ReadScreenShot()
  - Returns the OCR result to the main app

x86アプリケーションは変更されず、AdvancedScanはサポートされている場所で実行されます。

x86アプリケーションからヘルパーを呼び出す

ProcessStartInfo でヘルパーを起動し、その出力を読みます。

using System;
using System.Diagnostics;
using System.IO;
public static class OcrHelperClient
{
    public static string ReadScreenshotWithHelper(string imagePath)
    {
        string helperExePath = Path.Combine(
            AppDomain.CurrentDomain.BaseDirectory,
            "OcrHelper.x64",
            "OcrHelper.x64.exe"
        );
        if (!File.Exists(helperExePath))
        {
            throw new FileNotFoundException("The OCR helper executable was not found.", helperExePath);
        }
        var startInfo = new ProcessStartInfo
        {
            FileName = helperExePath,
            Arguments = "\"" + imagePath + "\"",
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        };
        using (var process = new Process())
        {
            process.StartInfo = startInfo;
            process.Start();
            string output = process.StandardOutput.ReadToEnd();
            string error = process.StandardError.ReadToEnd();
            process.WaitForExit();
            if (process.ExitCode != 0)
            {
                throw new Exception("OCR helper failed: " + error);
            }
            return output;
        }
    }
}
using System;
using System.Diagnostics;
using System.IO;
public static class OcrHelperClient
{
    public static string ReadScreenshotWithHelper(string imagePath)
    {
        string helperExePath = Path.Combine(
            AppDomain.CurrentDomain.BaseDirectory,
            "OcrHelper.x64",
            "OcrHelper.x64.exe"
        );
        if (!File.Exists(helperExePath))
        {
            throw new FileNotFoundException("The OCR helper executable was not found.", helperExePath);
        }
        var startInfo = new ProcessStartInfo
        {
            FileName = helperExePath,
            Arguments = "\"" + imagePath + "\"",
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        };
        using (var process = new Process())
        {
            process.StartInfo = startInfo;
            process.Start();
            string output = process.StandardOutput.ReadToEnd();
            string error = process.StandardError.ReadToEnd();
            process.WaitForExit();
            if (process.ExitCode != 0)
            {
                throw new Exception("OCR helper failed: " + error);
            }
            return output;
        }
    }
}
Imports System
Imports System.Diagnostics
Imports System.IO

Public Module OcrHelperClient
    Public Function ReadScreenshotWithHelper(imagePath As String) As String
        Dim helperExePath As String = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "OcrHelper.x64", "OcrHelper.x64.exe")
        If Not File.Exists(helperExePath) Then
            Throw New FileNotFoundException("The OCR helper executable was not found.", helperExePath)
        End If

        Dim startInfo As New ProcessStartInfo With {
            .FileName = helperExePath,
            .Arguments = """" & imagePath & """",
            .UseShellExecute = False,
            .RedirectStandardOutput = True,
            .RedirectStandardError = True,
            .CreateNoWindow = True
        }

        Using process As New Process()
            process.StartInfo = startInfo
            process.Start()
            Dim output As String = process.StandardOutput.ReadToEnd()
            Dim error As String = process.StandardError.ReadToEnd()
            process.WaitForExit()

            If process.ExitCode <> 0 Then
                Throw New Exception("OCR helper failed: " & error)
            End If

            Return output
        End Using
    End Function
End Module
$vbLabelText   $csharpLabel

StandardOutputStandardError の両方をリダイレクトすると、呼び出し側は認識されたテキストをキャプチャし、ヘルパーの終了コードから失敗を表面化できます。

string imagePath = @"C:\Images\Step_1-5.jpg";
string text = OcrHelperClient.ReadScreenshotWithHelper(imagePath);
Console.WriteLine(text);
string imagePath = @"C:\Images\Step_1-5.jpg";
string text = OcrHelperClient.ReadScreenshotWithHelper(imagePath);
Console.WriteLine(text);
Imports System

Dim imagePath As String = "C:\Images\Step_1-5.jpg"
Dim text As String = OcrHelperClient.ReadScreenshotWithHelper(imagePath)
Console.WriteLine(text)
$vbLabelText   $csharpLabel

x64ヘルパーの構築

ヘルパーをx64コンソールアプリとしてビルドし、IronOcrIronOcr.Extensions.AdvancedScan を参照させます。 それは最初の引数から画像パスを読み取り、OCRを実行し、結果をstdout に書き込みます。

using System;
using System.IO;
using IronOcr;
namespace OcrHelper.x64
{
    internal static class Program
    {
        private static int Main(string[] args)
        {
            try
            {
                if (args.Length == 0)
                {
                    Console.Error.WriteLine("Missing image path argument.");
                    return 1;
                }
                string imagePath = args[0];
                if (!File.Exists(imagePath))
                {
                    Console.Error.WriteLine("Image file was not found: " + imagePath);
                    return 2;
                }
                string licenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY");
                if (!string.IsNullOrWhiteSpace(licenseKey))
                {
                    License.LicenseKey = licenseKey;
                }
                var ocr = new IronTesseract();
                using (var input = new OcrInput())
                {
                    input.LoadImage(imagePath);
                    var result = ocr.ReadScreenShot(input);
                    Console.WriteLine(result.Text);
                }
                return 0;
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.ToString());
                return 99;
            }
        }
    }
}
using System;
using System.IO;
using IronOcr;
namespace OcrHelper.x64
{
    internal static class Program
    {
        private static int Main(string[] args)
        {
            try
            {
                if (args.Length == 0)
                {
                    Console.Error.WriteLine("Missing image path argument.");
                    return 1;
                }
                string imagePath = args[0];
                if (!File.Exists(imagePath))
                {
                    Console.Error.WriteLine("Image file was not found: " + imagePath);
                    return 2;
                }
                string licenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY");
                if (!string.IsNullOrWhiteSpace(licenseKey))
                {
                    License.LicenseKey = licenseKey;
                }
                var ocr = new IronTesseract();
                using (var input = new OcrInput())
                {
                    input.LoadImage(imagePath);
                    var result = ocr.ReadScreenShot(input);
                    Console.WriteLine(result.Text);
                }
                return 0;
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.ToString());
                return 99;
            }
        }
    }
}
Imports System
Imports System.IO
Imports IronOcr

Namespace OcrHelper.x64
    Friend Module Program
        Private Function Main(args As String()) As Integer
            Try
                If args.Length = 0 Then
                    Console.Error.WriteLine("Missing image path argument.")
                    Return 1
                End If

                Dim imagePath As String = args(0)
                If Not File.Exists(imagePath) Then
                    Console.Error.WriteLine("Image file was not found: " & imagePath)
                    Return 2
                End If

                Dim licenseKey As String = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY")
                If Not String.IsNullOrWhiteSpace(licenseKey) Then
                    License.LicenseKey = licenseKey
                End If

                Dim ocr As New IronTesseract()
                Using input As New OcrInput()
                    input.LoadImage(imagePath)
                    Dim result = ocr.ReadScreenShot(input)
                    Console.WriteLine(result.Text)
                End Using

                Return 0
            Catch ex As Exception
                Console.Error.WriteLine(ex.ToString())
                Return 99
            End Try
        End Function
    End Module
End Namespace
$vbLabelText   $csharpLabel

異なる終了コード(1, 2, 99)によって、呼び出しアプリケーションは、引数が欠けているのかファイルが欠けているのか、または予期しない例外かを判別できます。

本番利用の注意事項

サンプルは簡単にするためにstdout を使用します。 本番環境には、アーキテクチャに合った通信方法を選んでください。 オプションには以下があります:

  • 標準出力と標準エラー。
  • 一時的なJSONファイル。
  • 名前付きパイプ。
  • ローカルHTTPエンドポイント。
  • x64 OCR操作をホストするWindowsサービス。

小規模または頻繁でない呼び出しの場合:通常、必要に応じてヘルパーを起動するだけで大丈夫です。大容量のワークロードの場合:リクエストごとにプロセスを生成するよりも、長時間稼働するx64ヘルパーサービスがより効率的です。

デバッグのヒント

ヘルパーアプローチが誤動作する場合は、これらのチェックを実行します:

  • メインアプリケーションが本当にx86のままである必要があることを確認し、Ocr.Read() がスクリーンショットのシナリオに十分でないことを確認します。
  • ReadScreenShot() がx64プロセスから直接実行したときに成功することを確認します。
  • プラットフォームターゲット: x64でヘルパープロジェクトをビルドし、x86アプリがReadScreenShot() を自分で呼び出さないようにします。
  • x64ヘルパープロジェクトにIronOcr.Extensions.AdvancedScan をインストールします。
  • ヘルパーに渡される画像パスがヘルパープロセスからアクセス可能であることを確認してください。 コード、アプリ設定、またはIRONOCR_LICENSE_KEY 環境変数でIronOCRのライセンスキーを設定します。

ヘルパーを公開するときは、.exe のみでなく、ビルド出力全体をコピーします。 出力フォルダには、参照されるすべてのアセンブリとビルドによって生成されたネイティブランタイムファイルを含める必要があります。さもなくば、ヘルパーは同じ展開エラーに直面します。

Curtis Chau
テクニカルライター

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

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

準備はできましたか?
Nuget ダウンロード 6,136,090 | バージョン: 2026.7 リリースされたばかり
Still Scrolling Icon

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

すぐに証拠が欲しいですか? PM > Install-Package IronOcr
サンプルを実行 あなたの画像が検索可能なテキストになるのをご覧ください。